aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlban Peignier2018-04-19 23:42:20 +0200
committerGitHub2018-04-19 23:42:20 +0200
commit66257b30c12197d24018f234e73aa1da0631f04d (patch)
tree981332ae2da706d1f080e621045a53a0dc472fd1
parentba4cfd78bb9a750aa9f077392934cee39058a616 (diff)
parent34cf69c9cdebe5846426e6c69ab919d9c5a640a4 (diff)
downloadchouette-core-66257b30c12197d24018f234e73aa1da0631f04d.tar.bz2
Merge pull request #488 from af83/6477-use-custom-fields-in-checksums
Use custom fields values in checksum calculation. Refs #6477
-rw-r--r--app/models/concerns/checksum_support.rb1
-rw-r--r--app/models/concerns/custom_fields_support.rb4
-rw-r--r--app/models/custom_field.rb37
-rw-r--r--spec/fixtures/test_1/file.txt1
-rw-r--r--spec/fixtures/test_2/file.txt1
-rw-r--r--spec/models/chouette/vehicle_journey_spec.rb42
6 files changed, 83 insertions, 3 deletions
diff --git a/app/models/concerns/checksum_support.rb b/app/models/concerns/checksum_support.rb
index 92103798e..de3a6e16b 100644
--- a/app/models/concerns/checksum_support.rb
+++ b/app/models/concerns/checksum_support.rb
@@ -40,6 +40,7 @@ module ChecksumSupport
def current_checksum_source
source = checksum_replace_nil_or_empty_values(self.checksum_attributes)
+ source += self.custom_fields_checksum if self.respond_to?(:custom_fields_checksum)
source.map{ |item|
if item.kind_of?(Array)
item.map{ |x| x.kind_of?(Array) ? "(#{x.join(',')})" : x }.join(',')
diff --git a/app/models/concerns/custom_fields_support.rb b/app/models/concerns/custom_fields_support.rb
index 46fc8e73d..c39dfd1fc 100644
--- a/app/models/concerns/custom_fields_support.rb
+++ b/app/models/concerns/custom_fields_support.rb
@@ -28,6 +28,10 @@ module CustomFieldsSupport
CustomField::Collection.new self, workgroup
end
+ def custom_fields_checksum
+ custom_fields.values.map(&:checksum)
+ end
+
def custom_field_values= vals
out = {}
custom_fields.each do |code, field|
diff --git a/app/models/custom_field.rb b/app/models/custom_field.rb
index 65eabb205..88783b5b4 100644
--- a/app/models/custom_field.rb
+++ b/app/models/custom_field.rb
@@ -63,6 +63,10 @@ class CustomField < ApplicationModel
@raw_value
end
+ def checksum
+ @raw_value
+ end
+
def input form_helper
@input ||= begin
klass_name = field_type && "CustomField::Instance::#{field_type.classify}::Input"
@@ -187,9 +191,10 @@ class CustomField < ApplicationModel
custom_field_code = self.code
_attr_name = attr_name
_uploader_name = uploader_name
+ _digest_name = digest_name
owner.send :define_singleton_method, "read_uploader" do |attr|
if attr.to_s == _attr_name
- custom_field_values[custom_field_code]
+ custom_field_values[custom_field_code] && custom_field_values[custom_field_code]["path"]
else
read_attribute attr
end
@@ -197,16 +202,28 @@ class CustomField < ApplicationModel
owner.send :define_singleton_method, "write_uploader" do |attr, val|
if attr.to_s == _attr_name
- custom_field_values[custom_field_code] = val
+ self.custom_field_values[custom_field_code] ||= {}
+ self.custom_field_values[custom_field_code]["path"] = val
+ self.custom_field_values[custom_field_code]["digest"] = self.send _digest_name
else
write_attribute attr, val
end
end
owner.send :define_singleton_method, "#{_attr_name}_will_change!" do
+ self.send "#{_digest_name}=", nil
custom_field_values_will_change!
end
+ owner.send :define_singleton_method, _digest_name do
+ val = instance_variable_get "@#{_digest_name}"
+ if val.nil? && (file = send(_uploader_name)).present?
+ val = CustomField::Instance::Attachment.digest(file)
+ instance_variable_set "@#{_digest_name}", val
+ end
+ val
+ end
+
_extension_whitelist = options["extension_whitelist"]
owner.send :define_singleton_method, "#{_uploader_name}_extension_whitelist" do
@@ -215,7 +232,15 @@ class CustomField < ApplicationModel
unless owner.class.uploaders.has_key? _uploader_name.to_sym
owner.class.mount_uploader _uploader_name, CustomFieldAttachmentUploader, mount_on: "custom_field_#{code}_raw_value"
+ owner.class.send :attr_accessor, _digest_name
end
+
+ digest = @raw_value && @raw_value["digest"]
+ owner.send "#{_digest_name}=", digest
+ end
+
+ def self.digest file
+ Digest::SHA256.file(file.path).hexdigest
end
def preprocess_value_for_assignment val
@@ -226,6 +251,10 @@ class CustomField < ApplicationModel
end
end
+ def checksum
+ owner.send digest_name
+ end
+
def value
owner.send "custom_field_#{code}"
end
@@ -242,6 +271,10 @@ class CustomField < ApplicationModel
"custom_field_#{code}"
end
+ def digest_name
+ "#{uploader_name}_digest"
+ end
+
def display_value
render_partial
end
diff --git a/spec/fixtures/test_1/file.txt b/spec/fixtures/test_1/file.txt
new file mode 100644
index 000000000..3cd77f071
--- /dev/null
+++ b/spec/fixtures/test_1/file.txt
@@ -0,0 +1 @@
+TEST 1
diff --git a/spec/fixtures/test_2/file.txt b/spec/fixtures/test_2/file.txt
new file mode 100644
index 000000000..55d8fa4b0
--- /dev/null
+++ b/spec/fixtures/test_2/file.txt
@@ -0,0 +1 @@
+TEST 2
diff --git a/spec/models/chouette/vehicle_journey_spec.rb b/spec/models/chouette/vehicle_journey_spec.rb
index 6d44eeb2f..8682d59a2 100644
--- a/spec/models/chouette/vehicle_journey_spec.rb
+++ b/spec/models/chouette/vehicle_journey_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe Chouette::VehicleJourney, :type => :model do
subject { create(:vehicle_journey) }
-
+
it { should have_and_belong_to_many(:purchase_windows) }
it "must be valid with an at-stop day offset of 1" do
@@ -34,6 +34,46 @@ describe Chouette::VehicleJourney, :type => :model do
expect(vehicle_journey).to receive(:update_checksum_without_callbacks!).at_least(:once).and_call_original
expect{create(:vehicle_journey_at_stop, vehicle_journey: vehicle_journey)}.to change{vehicle_journey.checksum}
end
+
+ context "when custom_field_values change" do
+ let(:vehicle_journey){ create(:vehicle_journey, custom_field_values: {custom_field.code.to_s => former_value}) }
+ let(:custom_field){ create :custom_field, field_type: :string, code: :energy, name: :energy, resource_type: "VehicleJourney" }
+ let(:former_value){ "foo" }
+ let(:value){ "bar" }
+ before do
+ @checksum_source = vehicle_journey.checksum_source
+ end
+
+ it "should update the checksum" do
+ vehicle_journey.custom_field_values = {custom_field.code.to_s => value}
+ vehicle_journey.save
+ expect(vehicle_journey.checksum_source).to_not eq @checksum_source
+ end
+
+ context "with an attachment custom_field" do
+ let(:vehicle_journey) do
+ custom_field
+ vj = create(:vehicle_journey)
+ vj.custom_field_energy = File.open(fixtures_path("test_1/file.txt"))
+ vj.save
+ vj
+ end
+ let(:custom_field){ create :custom_field, field_type: :attachment, code: :energy, name: :energy, resource_type: "VehicleJourney" }
+
+ it "should update the checksum" do
+ expect(CustomField::Instance::Attachment).to receive(:digest).and_call_original
+ vehicle_journey.custom_field_energy = File.open(fixtures_path("test_2/file.txt"))
+ vehicle_journey.save
+ expect(vehicle_journey.checksum_source).to_not eq @checksum_source
+ end
+
+ it "should not calculate the digest if the vale does not change" do
+ expect(CustomField::Instance::Attachment).to_not receive(:digest).and_call_original
+ vehicle_journey.reload.save
+ expect(vehicle_journey.checksum_source).to eq @checksum_source
+ end
+ end
+ end
end
describe "#with_stop_area_ids" do