Skip to content

Commit ffa1ec1

Browse files
committed
support responseSetFilters, fix specs
1 parent 56dfb22 commit ffa1ec1

12 files changed

+73
-55
lines changed

Gemfile.lock

+3-3
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ GIT
88
PATH
99
remote: .
1010
specs:
11-
json_schema_form (0.10.1)
11+
json_schema_form (0.12.0)
1212
activesupport (~> 6)
1313
dry-schema (~> 1.10)
1414
json_schemer (= 0.2.17)
@@ -72,10 +72,10 @@ GEM
7272
rake (13.0.6)
7373
regexp_parser (2.5.0)
7474
ruby-progressbar (1.11.0)
75-
tzinfo (2.0.5)
75+
tzinfo (2.0.6)
7676
concurrent-ruby (~> 1.0)
7777
uri_template (0.7.0)
78-
zeitwerk (2.6.0)
78+
zeitwerk (2.6.7)
7979

8080
PLATFORMS
8181
ruby

lib/jsf/forms/condition.rb

+15-19
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ def errors(**passthru)
8484

8585
# @return [NilClass, String]
8686
def condition_property_key
87-
self.dig('if', 'properties')&.keys&.first
87+
dig('if', 'properties')&.keys&.first
8888
end
8989

9090
# @return [NilClass, String]
@@ -94,42 +94,38 @@ def condition_property
9494

9595
# @return [Boolean]
9696
def negated
97-
!!self.dig('if', 'properties', condition_property_key)&.key?('not')
97+
!!dig('if', 'properties', condition_property_key)&.key?('not')
9898
end
9999

100-
# @return [nil, 'enum', 'const']
100+
# @return [nil, 'enum', 'const', 'not_enum', 'not_const']
101101
def condition_type
102-
if negated
103-
self.dig('if', 'properties', condition_property_key, 'not')&.keys&.first
102+
hash = dig('if', 'properties', condition_property_key)
103+
return unless hash
104+
105+
if hash.key?('not')
106+
"not_#{hash['not'].keys.first}"
104107
else
105-
self.dig('if', 'properties', condition_property_key)&.keys&.first
108+
hash.keys.first
106109
end
107110
end
108111

109112
# @return [NilClass, String]
110113
def value
111-
if negated
112-
self.dig('if', 'properties', condition_property_key, 'not', condition_type)
113-
else
114-
self.dig('if', 'properties', condition_property_key, condition_type)
115-
end
114+
path = JSF::Forms::Form::CONDITION_TYPE_TO_PATH.call(condition_type)
115+
dig('if', 'properties', condition_property_key, *path)
116116
end
117117

118118
# Sets a new value for the condition
119119
#
120120
# @param [String, Boolean, Number] value
121-
# @param [Boolean] negated
122121
# @param ['const', 'enum']
123122
#
124123
# @return [void]
125-
def set_value(value, negated: self.negated, condition_type: self.condition_type)
126-
self.dig('if', 'properties')&.clear
127-
128-
path = ['if', 'properties', condition_property_key]
129-
path.push('not') if negated
130-
path.push(condition_type)
124+
def set_value(value, condition_type: self.condition_type)
125+
dig('if', 'properties')&.clear
131126

132-
SuperHash::Utils.bury(self, *path, value)
127+
path = JSF::Forms::Form::CONDITION_TYPE_TO_PATH.call(condition_type)
128+
SuperHash::Utils.bury(self, 'if', 'properties', condition_property_key, *path, value)
133129
end
134130

135131
# Takes a document or a part of a document (for nested hashes like JSF::Forms::Section) and

lib/jsf/forms/field/checkbox.rb

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ def validation_schema(passthru)
3232
end
3333
end
3434
required(:pictures).value(:array?).array(:str?)
35+
optional(:responseSetFilters).value(:array?).array(:str?)
3536
required(:sort).filled(:integer)
3637
required(:visibility).hash do
3738
required(:label).filled(:bool)

lib/jsf/forms/field/concerns/conditionable.rb

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ def insert_property_at_index(*args, **kwargs, &block)
1515
meta.dig(:parent).insert_conditional_property_at_index(*args, dependent_on: key_name, **kwargs, &block)
1616
end
1717

18-
def condition(*arguments, &block)
19-
meta.dig(:parent).condition(key_name, *arguments, &block)
18+
def find_or_add_condition(*arguments, &block)
19+
meta.dig(:parent).find_or_add_condition(key_name, *arguments, &block)
2020
end
2121

2222
# delegate

lib/jsf/forms/field/concerns/response_settable.rb

+13
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,19 @@ module ResponseSettable
1111
###VALIDATIONS####
1212
##################
1313

14+
# since we cannot augment the displayProperties schema, remove 'responseSetFilters' when valid
15+
# so it passes validations
16+
def validation_schema(passthru)
17+
Dry::Schema.define(parent: super) do
18+
before(:key_validator) do |result|
19+
hash = result.to_h
20+
d_p = hash['displayProperties']
21+
d_p.delete('responseSetFilters') if d_p && d_p['responseSetFilters'].is_a?(::Array)
22+
hash
23+
end
24+
end
25+
end
26+
1427
# # Consider response set
1528
# #
1629
# # @param [] locale

lib/jsf/forms/field/select.rb

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ def validation_schema(passthru)
3434
end
3535
end
3636
required(:pictures).value(:array?).array(:str?)
37+
optional(:responseSetFilters).value(:array?).array(:str?)
3738
required(:sort).filled(:integer)
3839
required(:visibility).hash do
3940
required(:label).filled(:bool)

lib/jsf/forms/form.rb

+16-10
Original file line numberDiff line numberDiff line change
@@ -633,15 +633,21 @@ def resort!
633633
#
634634
# @param dependent_on [Symbol] name of property the condition depends on
635635
# @param type [Symbol] type of condition to filter by
636-
# @param value [String,Boolean,Integer] Value that makes the condition TRUE
637-
# @return [JSF::Schema]
638-
def get_condition(dependent_on, type, value)
636+
# @param value [*] Value that makes the condition TRUE
637+
# @return [Array<JSF::Schema>, NilClass]
638+
def get_conditions(dependent_on, type, value=nil)
639639
cond_path = CONDITION_TYPE_TO_PATH.call(type)
640-
self[:allOf]&.find do |condition|
641-
if [:enum, :not_enum].include?(type)
642-
condition.dig(:if, :properties, dependent_on, *cond_path)&.include?(value)
640+
641+
self[:allOf]&.select do |condition|
642+
prop_schema = condition.dig(:if, :properties, dependent_on)
643+
next unless prop_schema
644+
645+
condition_value = prop_schema.dig(*cond_path)
646+
647+
if [:enum, :not_enum].include?(type.to_sym)
648+
condition_value&.include?(value)
643649
else
644-
condition.dig(:if, :properties, dependent_on, *cond_path) == value
650+
condition_value == value
645651
end
646652
end
647653
end
@@ -668,8 +674,8 @@ def add_condition(dependent_on, type, value)
668674
self[:allOf].last
669675
end
670676

671-
def condition(dependent_on, type, value, &block)
672-
condition = get_condition(dependent_on, type, value) || add_condition(dependent_on, type, value)
677+
def find_or_add_condition(dependent_on, type, value, &block)
678+
condition = get_conditions(dependent_on, type, value)&.first || add_condition(dependent_on, type, value)
673679
condition[:then].instance_eval(&block) if block_given?
674680
condition
675681
end
@@ -688,7 +694,7 @@ def insert_conditional_property_at_index(sort_value, property_id, definition, de
688694
raise ArgumentError.new("sort must be an Integer, :prepend or :append, got #{sort_value}")
689695
end
690696

691-
condition = condition(dependent_on, type, value)
697+
condition = find_or_add_condition(dependent_on, type, value)
692698
subform = condition[:then]
693699

694700
case sort_value

lib/jsf/forms/response.rb

+1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ def validation_schema(passthru)
4242
end
4343
end
4444
optional(:color).maybe(:string)
45+
optional(:tags).value(:array?).array(:str?)
4546
end
4647
if passthru[:is_inspection]
4748
required(:enableScore).value(Types::True) #deprecate?

lib/jsf/version.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
module JSF
2-
VERSION = "0.11.0"
2+
VERSION = "0.12.0"
33
end

test/spec/forms/condition_spec.rb

+7-7
Original file line numberDiff line numberDiff line change
@@ -69,11 +69,11 @@ def test_condition_type
6969

7070
# not const
7171
instance['if']['properties']['some_prop'] = { not: { const: true } }
72-
assert_equal 'const', instance.condition_type
72+
assert_equal 'not_const', instance.condition_type
7373

7474
# not enum
7575
instance['if']['properties']['some_prop'] = { not: { enum: true } }
76-
assert_equal 'enum', instance.condition_type
76+
assert_equal 'not_enum', instance.condition_type
7777

7878
# const
7979
instance['if']['properties']['some_prop'] = { const: true }
@@ -123,17 +123,17 @@ def test_set_value
123123

124124
instance.set_value(1)
125125
assert_equal true, instance.negated
126-
assert_equal 'const', instance.condition_type
126+
assert_equal 'not_const', instance.condition_type
127127
assert_equal 1, instance.value
128128

129129
instance.set_value(2, condition_type: 'enum')
130-
assert_equal true, instance.negated
130+
assert_equal false, instance.negated
131131
assert_equal 'enum', instance.condition_type
132132
assert_equal 2, instance.value
133133

134-
instance.set_value(3, condition_type: 'enum', negated: false)
135-
assert_equal false, instance.negated
136-
assert_equal 'enum', instance.condition_type
134+
instance.set_value(3, condition_type: 'not_enum')
135+
assert_equal true, instance.negated
136+
assert_equal 'not_enum', instance.condition_type
137137
assert_equal 3, instance.value
138138
end
139139

test/spec/forms/form_builder_spec.rb

+5-5
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ class FormbuilderTest < Minitest::Test
88
def test_fixtures
99
klasses = {
1010
JSF::Forms::SharedRef => [
11-
{errors_args: {unless: ->(i, key){key = :ref_presence} }}
11+
{errors_args: {unless: ->(i, key){key == :ref_presence} }}
1212
],
1313
JSF::Forms::Form => [],
1414
JSF::Forms::ResponseSet => [],
@@ -20,18 +20,18 @@ def test_fixtures
2020

2121
# fields
2222
JSF::Forms::Field::Checkbox => [
23-
{errors_args: {unless: ->(i, key){key = :ref_presence} }}
23+
{errors_args: {unless: ->(i, key){key == :ref_presence} }}
2424
],
2525
JSF::Forms::Field::Shared => [
26-
{errors_args: {unless: ->(i, key){key = :ref_presence} }}
26+
{errors_args: {unless: ->(i, key){key == :ref_presence} }}
2727
],
2828
JSF::Forms::Field::DateInput => [],
2929
JSF::Forms::Field::FileInput => [],
3030
JSF::Forms::Field::GeoPoints => [],
3131
JSF::Forms::Field::Markdown => [],
3232
JSF::Forms::Field::NumberInput => [],
3333
JSF::Forms::Field::Select => [
34-
{errors_args: {unless: ->(i, key){key = :ref_presence} }}
34+
{errors_args: {unless: ->(i, key){key == :ref_presence} }}
3535
],
3636
JSF::Forms::Field::Signature => [],
3737
JSF::Forms::Field::Slider => [],
@@ -88,7 +88,7 @@ def test_builder_example
8888
append_property :depedendent_select1, example('select'), type: :const, value: 'option1'
8989
append_property :depedendent_select2, example('select'), type: :enum, value: ['option1']
9090

91-
condition(:const, 'option2') do
91+
find_or_add_condition(:const, 'option2') do
9292
append_property(:depedendent_select3, example('select')) do |f|
9393
f.response_set_id = :response_set_1
9494
f.hidden = true

test/spec/forms/form_spec.rb

+8-8
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,7 @@ def test_resort!
516516
assert_equal 2, form.get_property('switch_3').sort
517517
end
518518

519-
def test_get_condition
519+
def test_get_conditions
520520
form = JSF::Forms::FormBuilder.build() do
521521
append_property(:prop1, example('select'))
522522
add_condition('prop1', :const, 'const')
@@ -526,16 +526,16 @@ def test_get_condition
526526
end
527527

528528
# found
529-
assert_equal 'const', form.get_condition(:prop1, :const, 'const')&.dig(:if, :properties, :prop1, :const)
530-
assert_equal 'not_const', form.get_condition(:prop1, :not_const, 'not_const')&.dig(:if, :properties, :prop1, :not, :const)
531-
assert_equal 'enum', form.get_condition(:prop1, :enum, 'enum')&.dig(:if, :properties, :prop1, :enum)&.first
532-
assert_equal 'not_enum', form.get_condition(:prop1, :not_enum, 'not_enum')&.dig(:if, :properties, :prop1, :not, :enum)&.first
529+
assert_equal 'const', form.get_conditions(:prop1, :const, 'const').first.dig(:if, :properties, :prop1, :const)
530+
assert_equal 'not_const', form.get_conditions(:prop1, :not_const, 'not_const').first.dig(:if, :properties, :prop1, :not, :const)
531+
assert_equal ['enum'], form.get_conditions(:prop1, :enum, 'enum').first.dig(:if, :properties, :prop1, :enum)
532+
assert_equal ['not_enum'], form.get_conditions(:prop1, :not_enum, 'not_enum').first.dig(:if, :properties, :prop1, :not, :enum)
533533

534534
# not found
535-
assert_nil form.get_condition(:prop1, :const, 'other_value')
535+
assert_nil form.get_conditions(:prop1, :const, 'other_value').first
536536

537537
# invalid key
538-
assert_raises(ArgumentError){ form.get_condition(:prop1, :wrong_key, 'other_value') }
538+
assert_raises(ArgumentError){ form.get_conditions(:prop1, :wrong_key, 'other_value') }
539539
end
540540

541541
def test_add_condition
@@ -1233,7 +1233,7 @@ def test_scored?
12331233
# non root
12341234
complex_non_scorable_form = JSF::Forms::FormBuilder.build do
12351235
append_property(:number_input_1, example('number_input')) do |f|
1236-
condition(:const, 1) do
1236+
find_or_add_condition(:const, 1) do
12371237
append_property(:markdown_1_1, example('markdown'), type: :const, value: 1)
12381238
append_property(:section, example('section')) do |f|
12391239
f.form.instance_eval do

0 commit comments

Comments
 (0)