Merge pull request #6393 from techAPJ/bad-json

FIX: ignore and log bad json values for custom fields
This commit is contained in:
Arpit Jalan 2018-09-13 15:54:01 +05:30 committed by GitHub
commit d288462abf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 59 additions and 4 deletions

View File

@ -42,13 +42,20 @@ module HasCustomFields
case type case type
when :boolean then !!CUSTOM_FIELD_TRUE.include?(value) when :boolean then !!CUSTOM_FIELD_TRUE.include?(value)
when :integer then value.to_i when :integer then value.to_i
when :json then ::JSON.parse(value) when :json then parse_json_value(value, key)
else else
value value
end end
array ? [result] : result array ? [result] : result
end end
def self.parse_json_value(value, key)
::JSON.parse(value)
rescue JSON::ParserError
Rails.logger.warn("Value '#{value}' for custom field '#{key}' is not json, it is being ignored.")
{}
end
end end
included do included do
@ -85,6 +92,11 @@ module HasCustomFields
@custom_field_types[name] = type @custom_field_types[name] = type
end end
def self.get_custom_field_type(name)
@custom_field_types ||= {}
@custom_field_types[name]
end
def self.preload_custom_fields(objects, fields) def self.preload_custom_fields(objects, fields)
if objects.present? if objects.present?
map = {} map = {}
@ -186,7 +198,7 @@ module HasCustomFields
array_fields = {} array_fields = {}
_custom_fields.reload.each do |f| _custom_fields.reload.each do |f|
if dup[f.name].is_a? Array if dup[f.name].is_a?(Array)
# we need to collect Arrays fully before we can compare them # we need to collect Arrays fully before we can compare them
if !array_fields.has_key?(f.name) if !array_fields.has_key?(f.name)
array_fields[f.name] = [f] array_fields[f.name] = [f]
@ -221,12 +233,14 @@ module HasCustomFields
end end
dup.each do |k, v| dup.each do |k, v|
if v.is_a? Array field_type = self.class.get_custom_field_type(k)
if v.is_a?(Array) && field_type != :json
v.each { |subv| _custom_fields.create!(name: k, value: subv) } v.each { |subv| _custom_fields.create!(name: k, value: subv) }
else else
_custom_fields.create!( _custom_fields.create!(
name: k, name: k,
value: v.is_a?(Hash) ? v.to_json : v value: v.is_a?(Hash) || field_type == :json ? v.to_json : v
) )
end end
end end

View File

@ -187,6 +187,47 @@ describe HasCustomFields do
expect(test_item2.custom_fields).to eq("sixto" => "rodriguez", "de" => "la playa") expect(test_item2.custom_fields).to eq("sixto" => "rodriguez", "de" => "la playa")
end end
it "supports arrays in json fields" do
field_type = "json_array"
CustomFieldsTestItem.register_custom_field_type(field_type, :json)
item = CustomFieldsTestItem.new
item.custom_fields = {
"json_array" => [{ a: "test" }, { b: "another" }]
}
item.save
item.reload
expect(item.custom_fields[field_type]).to eq(
[{ "a" => "test" }, { "b" => "another" }]
)
item.custom_fields["json_array"] = ['a', 'b']
item.save
item.reload
expect(item.custom_fields[field_type]).to eq(["a", "b"])
end
it "will not fail to load custom fields if json is corrupt" do
field_type = "bad_json"
CustomFieldsTestItem.register_custom_field_type(field_type, :json)
item = CustomFieldsTestItem.create!
CustomFieldsTestItemCustomField.create!(
custom_fields_test_item_id: item.id,
name: field_type,
value: "{test"
)
item = item.reload
expect(item.custom_fields[field_type]).to eq({})
end
it "supports bulk retrieval with a list of ids" do it "supports bulk retrieval with a list of ids" do
item1 = CustomFieldsTestItem.new item1 = CustomFieldsTestItem.new
item1.custom_fields = { "a" => ["b", "c", "d"], 'not_whitelisted' => 'secret' } item1.custom_fields = { "a" => ["b", "c", "d"], 'not_whitelisted' => 'secret' }