diff options
| -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 | 
