From 75d1042bbb7e495bc026ef08372633f944dbde89 Mon Sep 17 00:00:00 2001 From: Stephen Paul Weber Date: Wed, 13 Oct 2021 13:41:08 -0500 Subject: [PATCH] Easy DSL for adding XEP-0122 validation to fields --- lib/form_template.rb | 26 +++++++++++++-- test/test_form_template.rb | 68 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+), 2 deletions(-) diff --git a/lib/form_template.rb b/lib/form_template.rb index ffe7ccd..422ec71 100644 --- a/lib/form_template.rb +++ b/lib/form_template.rb @@ -48,8 +48,30 @@ class FormTemplate @__form.instructions = s end - def field(**kwargs) - @__form.fields = @__form.fields + [kwargs] + def validate(f, datatype: nil, **kwargs) + Nokogiri::XML::Builder.with(f) do |x| + x.validate( + xmlns: "http://jabber.org/protocol/xdata-validate", + datatype: datatype || "xs:string" + ) do + x.basic unless validation_type(x, **kwargs) + end + end + end + + def validation_type(x, open: false, regex: nil, range: nil) + x.open if open + x.range(min: range.first, max: range.last) if range + x.regex(regex.source) if regex + open || regex || range + end + + def field(datatype: nil, open: false, regex: nil, range: nil, **kwargs) + f = Blather::Stanza::X::Field.new(kwargs) + if datatype || open || regex || range + validate(f, datatype: datatype, open: open, regex: regex, range: range) + end + @__form.fields += [f] end def xml diff --git a/test/test_form_template.rb b/test/test_form_template.rb index 78c4e0e..8015d91 100644 --- a/test/test_form_template.rb +++ b/test/test_form_template.rb @@ -46,6 +46,74 @@ class FormTemplateTest < Minitest::Test assert_equal "INSTRUCTIONS", form.instructions end + def test_form_validate_basic + template = FormTemplate.new(<<~TEMPLATE) + form! + field(var: "thevar", label: "thelabel", datatype: "xs:integer") + TEMPLATE + form = template.render + assert_equal 1, form.fields.length + assert_equal "thevar", form.fields[0].var + assert_equal "thelabel", form.fields[0].label + validate = form.fields[0].find( + "ns:validate", + ns: "http://jabber.org/protocol/xdata-validate" + ).first + assert_equal "xs:integer", validate[:datatype] + assert_equal "basic", validate.children.first.name + end + + def test_form_validate_open + template = FormTemplate.new(<<~TEMPLATE) + form! + field(var: "thevar", label: "thelabel", open: true) + TEMPLATE + form = template.render + assert_equal 1, form.fields.length + assert_equal "thevar", form.fields[0].var + assert_equal "thelabel", form.fields[0].label + validate = form.fields[0].find( + "ns:validate", + ns: "http://jabber.org/protocol/xdata-validate" + ).first + assert_equal ["open"], validate.children.map(&:name) + end + + def test_form_validate_regex + template = FormTemplate.new(<<~TEMPLATE) + form! + field(var: "thevar", label: "thelabel", regex: /[A-Z]/) + TEMPLATE + form = template.render + assert_equal 1, form.fields.length + assert_equal "thevar", form.fields[0].var + assert_equal "thelabel", form.fields[0].label + validate = form.fields[0].find( + "ns:validate", + ns: "http://jabber.org/protocol/xdata-validate" + ).first + assert_equal ["regex"], validate.children.map(&:name) + assert_equal "[A-Z]", validate.children.first.content + end + + def test_form_validate_range + template = FormTemplate.new(<<~TEMPLATE) + form! + field(var: "thevar", label: "thelabel", range: (10..22)) + TEMPLATE + form = template.render + assert_equal 1, form.fields.length + assert_equal "thevar", form.fields[0].var + assert_equal "thelabel", form.fields[0].label + validate = form.fields[0].find( + "ns:validate", + ns: "http://jabber.org/protocol/xdata-validate" + ).first + assert_equal ["range"], validate.children.map(&:name) + assert_equal "10", validate.children.first[:min] + assert_equal "22", validate.children.first[:max] + end + def test_no_type template = FormTemplate.new(<<~TEMPLATE) title "TITLE" -- 2.34.5