diff options
author | Tomasz Maczukin <tomasz@maczukin.pl> | 2018-03-21 17:22:52 +0100 |
---|---|---|
committer | Tomasz Maczukin <tomasz@maczukin.pl> | 2018-03-28 13:58:35 +0200 |
commit | c747d9bc0b35d2982f45e2e8a0bdaa305f504f38 (patch) | |
tree | c1f6ebb697c3d0f169e1f3659a7499e782a511de | |
parent | ed86344f4941ce8b30546260b8437451026c8d97 (diff) | |
download | gitlab-ce-c747d9bc0b35d2982f45e2e8a0bdaa305f504f38.tar.gz |
Add validation for chronic_duration_attr_writer
-rw-r--r-- | app/models/concerns/chronic_duration_attribute.rb | 27 | ||||
-rw-r--r-- | spec/models/concerns/chronic_duration_attribute_spec.rb | 66 |
2 files changed, 74 insertions, 19 deletions
diff --git a/app/models/concerns/chronic_duration_attribute.rb b/app/models/concerns/chronic_duration_attribute.rb index 15095d0b758..ad8934f58d8 100644 --- a/app/models/concerns/chronic_duration_attribute.rb +++ b/app/models/concerns/chronic_duration_attribute.rb @@ -18,13 +18,32 @@ module ChronicDurationAttribute end def chronic_duration_attr_writer(virtual_attribute, source_attribute) + virtual_attribute_validator = "#{virtual_attribute}_validator".to_sym + validation_error = "#{virtual_attribute}_error".to_sym + + validate virtual_attribute_validator + attr_accessor validation_error + define_method("#{virtual_attribute}=") do |value| - new_value = ChronicDuration.parse(value).to_i unless value.nil? - new_value = nil if !new_value.nil? && new_value <= 0 + begin + self.send("#{validation_error}=", '') # rubocop:disable GitlabSecurity/PublicSend - self.send("#{source_attribute}=", new_value) # rubocop:disable GitlabSecurity/PublicSend + new_value = + if value.blank? + nil + else + ChronicDuration.parse(value).to_i + end + + self.send("#{source_attribute}=", new_value) # rubocop:disable GitlabSecurity/PublicSend + rescue ChronicDuration::DurationParseError => ex + self.send("#{validation_error}=", ex.message) # rubocop:disable GitlabSecurity/PublicSend + end + end - new_value + define_method(virtual_attribute_validator) do + error = self.send(validation_error) # rubocop:disable GitlabSecurity/PublicSend + self.send('errors').add(source_attribute, error) unless error.blank? # rubocop:disable GitlabSecurity/PublicSend end end end diff --git a/spec/models/concerns/chronic_duration_attribute_spec.rb b/spec/models/concerns/chronic_duration_attribute_spec.rb index cfbf83dab54..fea3e752ab5 100644 --- a/spec/models/concerns/chronic_duration_attribute_spec.rb +++ b/spec/models/concerns/chronic_duration_attribute_spec.rb @@ -11,10 +11,12 @@ shared_examples 'ChronicDurationAttribute reader' do expect(subject.send(virtual_field)).to eq('2m') end - it 'outputs empty string when value set to nil' do - subject.send("#{source_field}=", nil) + context 'when value is set to nil' do + it 'outputs empty string' do + subject.send("#{source_field}=", nil) - expect(subject.send(virtual_field)).to be_empty + expect(subject.send(virtual_field)).to be_empty + end end end @@ -29,28 +31,62 @@ shared_examples 'ChronicDurationAttribute writer' do expect(subject.send(source_field)).to eq(600) end - it 'writes nil when empty input is used' do - subject.send("#{virtual_field}=", '') + it 'passes validation' do + subject.send("#{virtual_field}=", '10m') - expect(subject.send(source_field)).to be_nil + expect(subject.valid?).to be_truthy end - it 'writes nil when negative input is used' do - allow(ChronicDuration).to receive(:parse).and_return(-10) + context 'when negative input is used' do + before do + subject.send("#{source_field}=", 3600) + end + + it "doesn't raise exception" do + expect { subject.send("#{virtual_field}=", '-10m') }.not_to raise_error(ChronicDuration::DurationParseError) + end + + it "doesn't change value" do + expect { subject.send("#{virtual_field}=", '-10m') }.not_to change { subject.send(source_field) } + end - subject.send("#{virtual_field}=", '-10m') + it "doesn't pass validation" do + subject.send("#{virtual_field}=", '-10m') - expect(subject.send(source_field)).to be_nil + expect(subject.valid?).to be_falsey + end end - it 'writes nil when nil input is used' do - subject.send("#{virtual_field}=", nil) + context 'when empty input is used' do + it 'writes nil' do + subject.send("#{virtual_field}=", '') + + expect(subject.send(source_field)).to be_nil + end + + it 'passes validation' do + subject.send("#{virtual_field}=", '') - expect(subject.send(source_field)).to be_nil + expect(subject.valid?).to be_truthy + end end - it "doesn't raise exception when nil input is used" do - expect { subject.send("#{virtual_field}=", nil) }.not_to raise_error(NoMethodError) + context 'when nil input is used' do + it 'writes nil' do + subject.send("#{virtual_field}=", nil) + + expect(subject.send(source_field)).to be_nil + end + + it 'passes validation' do + subject.send("#{virtual_field}=", nil) + + expect(subject.valid?).to be_truthy + end + + it "doesn't raise exception" do + expect { subject.send("#{virtual_field}=", nil) }.not_to raise_error(NoMethodError) + end end end |