diff options
| author | Alban Peignier | 2018-04-19 23:42:20 +0200 |
|---|---|---|
| committer | GitHub | 2018-04-19 23:42:20 +0200 |
| commit | 66257b30c12197d24018f234e73aa1da0631f04d (patch) | |
| tree | 981332ae2da706d1f080e621045a53a0dc472fd1 | |
| parent | ba4cfd78bb9a750aa9f077392934cee39058a616 (diff) | |
| parent | 34cf69c9cdebe5846426e6c69ab919d9c5a640a4 (diff) | |
| download | chouette-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.rb | 1 | ||||
| -rw-r--r-- | app/models/concerns/custom_fields_support.rb | 4 | ||||
| -rw-r--r-- | app/models/custom_field.rb | 37 | ||||
| -rw-r--r-- | spec/fixtures/test_1/file.txt | 1 | ||||
| -rw-r--r-- | spec/fixtures/test_2/file.txt | 1 | ||||
| -rw-r--r-- | spec/models/chouette/vehicle_journey_spec.rb | 42 |
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 |
