Fixes #3647 - Error 500 / zammad {"error":" 123456 is out of range for ActiveModel::Type::Integer with limit 4 bytes"}

This commit is contained in:
Mantas Masalskis 2021-08-18 06:48:16 +02:00
parent 0668e17d18
commit 92822b6713
6 changed files with 180 additions and 6 deletions

View file

@ -279,7 +279,7 @@ class App.UiElement.object_manager_attribute extends App.UiElement.ApplicationUi
params: params params: params
) )
configureAttributes = [ configureAttributes = [
{ name: 'data_option::min', display: 'Minimal', tag: 'integer', null: false, default: 0, min: 1 }, { name: 'data_option::min', display: 'Minimal', tag: 'integer', null: false, default: 0, min: -2147483647, max: 2147483647 },
] ]
integerMin = new App.ControllerForm( integerMin = new App.ControllerForm(
model: model:
@ -288,7 +288,7 @@ class App.UiElement.object_manager_attribute extends App.UiElement.ApplicationUi
params: params params: params
) )
configureAttributes = [ configureAttributes = [
{ name: 'data_option::max', display: 'Maximal', tag: 'integer', null: false, default: 999999999, min: 2 }, { name: 'data_option::max', display: 'Maximal', tag: 'integer', null: false, min: -2147483647, max: 2147483647, default: 999999999 },
] ]
integerMax = new App.ControllerForm( integerMax = new App.ControllerForm(
model: model:

View file

@ -22,6 +22,10 @@ class ObjectManager::Attribute < ApplicationModel
active active
].freeze ].freeze
VALIDATE_INTEGER_MIN = -2_147_483_647
VALIDATE_INTEGER_MAX = 2_147_483_647
VALIDATE_INTEGER_REGEXP = %r{^-?\d+$}.freeze
self.table_name = 'object_manager_attributes' self.table_name = 'object_manager_attributes'
belongs_to :object_lookup, optional: true belongs_to :object_lookup, optional: true
@ -897,10 +901,23 @@ is certain attribute used by triggers, overviews or schedulers
[{ failed: !local_data_option[:maxlength].to_s.match?(%r{^\d+$}), [{ failed: !local_data_option[:maxlength].to_s.match?(%r{^\d+$}),
message: 'must have integer for :maxlength' }] message: 'must have integer for :maxlength' }]
when 'integer' when 'integer'
[{ failed: !local_data_option[:min].to_s.match?(%r{^\d+$}), min = local_data_option[:min]
max = local_data_option[:max]
[{ failed: !VALIDATE_INTEGER_REGEXP.match?(min.to_s),
message: 'must have integer for :min' }, message: 'must have integer for :min' },
{ failed: !local_data_option[:max].to_s.match?(%r{^\d+$}), { failed: !VALIDATE_INTEGER_REGEXP.match?(max.to_s),
message: 'must have integer for :max' }] message: 'must have integer for :max' },
{ failed: !(min.is_a?(Integer) && min >= VALIDATE_INTEGER_MIN),
message: 'min must be higher than -2147483648' },
{ failed: !(min.is_a?(Integer) && min <= VALIDATE_INTEGER_MAX),
message: 'min must be lower than 2147483648' },
{ failed: !(max.is_a?(Integer) && max >= VALIDATE_INTEGER_MIN),
message: 'max must be higher than -2147483648' },
{ failed: !(max.is_a?(Integer) && max <= VALIDATE_INTEGER_MAX),
message: 'max must be lower than 2147483648' },
{ failed: !(max.is_a?(Integer) && min.is_a?(Integer) && min <= max),
message: 'min must be lower than max' }]
when %r{^((tree_)?select|checkbox)$} when %r{^((tree_)?select|checkbox)$}
[{ failed: !local_data_option.key?(:default), [{ failed: !local_data_option.key?(:default),
message: 'must have value for :default' }, message: 'must have value for :default' },

View file

@ -0,0 +1,18 @@
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
class Issue3647CustomObjectAttributeInteger < ActiveRecord::Migration[6.0]
def up
return if !Setting.exists?(name: 'system_init_done')
%i[min max].each do |attr|
ObjectManager::Attribute
.where(data_type: 'integer', editable: true)
.each do |attribute|
next if attribute.data_option[attr] <= 2_147_483_647
attribute.data_option[attr] = 2_147_483_647
attribute.save!(validate: false)
end
end
end
end

View file

@ -0,0 +1,34 @@
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
require 'rails_helper'
RSpec.describe Issue3647CustomObjectAttributeInteger, type: :db_migration do
let(:integer_valid) { create(:object_manager_attribute_integer) }
let(:integer_max_over_max) do
object = build(:object_manager_attribute_integer, data_option: { default: 0, min: 0, max: 9_999_999_999 })
object.save(validate: false)
object
end
let(:integer_min_over_max) do
object = build(:object_manager_attribute_integer, data_option: { default: 0, min: 9_999_999_999, max: 99_999_999_999 })
object.save(validate: false)
object
end
it 'leaves valid integer intact' do
expect { migrate }
.not_to change { integer_valid.data_option[:max] }
end
it 'lowers max if it is too big' do
expect { migrate }
.to change { integer_max_over_max.reload.data_option[:max] }
.to 2_147_483_647
end
it 'lowers min if it is too big' do
expect { migrate }
.to change { integer_min_over_max.reload.data_option[:min] }
.to 2_147_483_647
end
end

View file

@ -3,7 +3,7 @@
module ZammadAuthenticatedAsHelper module ZammadAuthenticatedAsHelper
# parse authenticated_as params for request and system test helpers # parse authenticated_as params for request and system test helpers
# #
# @param input [Any] any to parse, see bellow for options # @param input [Any] any to parse, see below for options
# @param return_type [Symbol] :credentials or :user # @param return_type [Symbol] :credentials or :user
def authenticated_as_get_user(input, return_type:) def authenticated_as_get_user(input, return_type:)
case input case input

View file

@ -113,4 +113,109 @@ RSpec.describe 'Admin Panel > Objects', type: :system do
expect(ObjectManager::Attribute.last.data_option['options']).to eq(expected_data_options) expect(ObjectManager::Attribute.last.data_option['options']).to eq(expected_data_options)
end end
# https://github.com/zammad/zammad/issues/3647
context 'when setting Min/Max values for integer' do
before do
page.find('.js-new').click
in_modal disappears: false do
fill_in 'Name', with: 'integer1'
fill_in 'Display', with: 'Integer1'
page.find('select[name=data_type]').select('Integer')
end
end
it 'verifies max value does not go above limit' do
in_modal disappears: false do
fill_in 'Maximal', with: '999999999999'
page.find('.js-submit').click
expect(page).to have_text 'Data option max must be lower than 2147483648'
end
end
it 'verifies max value does not go below limit' do
in_modal disappears: false do
fill_in 'Maximal', with: '-999999999999'
page.find('.js-submit').click
expect(page).to have_text 'Data option max must be higher than -2147483648'
end
end
it 'verifies max value can be set' do
in_modal do
fill_in 'Maximal', with: '128'
page.find('.js-submit').click
end
expect(page).to have_text 'Integer1'
end
it 'verifies max value can be set to a negative value' do
in_modal do
fill_in 'Minimal', with: '-256'
fill_in 'Maximal', with: '-128'
page.find('.js-submit').click
end
expect(page).to have_text 'Integer1'
end
it 'verifies min value does not go above limit' do
in_modal disappears: false do
fill_in 'Minimal', with: '999999999999'
page.find('.js-submit').click
expect(page).to have_text 'Data option min must be lower than 2147483648'
end
end
it 'verifies min value does not go below limit' do
in_modal disappears: false do
fill_in 'Minimal', with: '-999999999999'
page.find('.js-submit').click
expect(page).to have_text 'Data option min must be higher than -2147483648'
end
end
it 'verifies min value can be set' do
in_modal do
fill_in 'Minimal', with: '128'
page.find('.js-submit').click
end
expect(page).to have_text 'Integer1'
end
it 'verifies min value can be set to a negative value' do
in_modal do
fill_in 'Minimal', with: '-128'
page.find('.js-submit').click
end
expect(page).to have_text 'Integer1'
end
it 'verifies min value must be lower than max' do
in_modal disappears: false do
fill_in 'Minimal', with: '128'
fill_in 'Maximal', with: '-128'
page.find('.js-submit').click
expect(page).to have_text 'Data option min must be lower than max'
end
end
end
end end