Changeset

11070:f7f30a3464fe

util.dataforms: Add support for validating (integer) ranges
author Kim Alvefur <zash@zash.se>
date Thu, 21 Nov 2019 18:56:43 +0100
parents 11069:770a5923e959
children 11074:3473bc8d80c9
files spec/util_dataforms_spec.lua util/dataforms.lua
diffstat 2 files changed, 22 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/spec/util_dataforms_spec.lua	Wed Sep 16 18:16:08 2020 +0200
+++ b/spec/util_dataforms_spec.lua	Thu Nov 21 18:56:43 2019 +0100
@@ -423,6 +423,8 @@
 				name = "number",
 				type = "text-single",
 				datatype = "xs:integer",
+				range_min = -10,
+				range_max = 10,
 			},
 		};
 
@@ -437,6 +439,13 @@
 			assert.table(e);
 			assert.string(e.number);
 		end);
+
+		it("works", function ()
+			local d,e = f:data(f:form({number = 100}));
+			assert.not_equal(100, d.number);
+			assert.table(e);
+			assert.string(e.number);
+		end);
 	end);
 	describe("media element", function ()
 		it("produced media element correctly", function ()
--- a/util/dataforms.lua	Wed Sep 16 18:16:08 2020 +0200
+++ b/util/dataforms.lua	Thu Nov 21 18:56:43 2019 +0100
@@ -10,6 +10,7 @@
 local ipairs = ipairs;
 local type, next = type, next;
 local tonumber = tonumber;
+local tostring = tostring;
 local t_concat = table.concat;
 local st = require "util.stanza";
 local jid_prep = require "util.jid".prep;
@@ -54,6 +55,12 @@
 
 		if formtype == "form" and field.datatype then
 			form:tag("validate", { xmlns = xmlns_validate, datatype = field.datatype });
+			if field.range_min or field.range_max then
+				form:tag("range", {
+						min = field.range_min and tostring(field.range_min),
+						max = field.range_max and tostring(field.range_max),
+					}):up();
+			end
 			-- <basic/> assumed
 			form:up();
 		end
@@ -290,13 +297,18 @@
 	end
 
 data_validators["xs:integer"] =
-	function (data)
+	function (data, field)
 		local n = tonumber(data);
 		if not n then
 			return false, "not a number";
 		elseif n % 1 ~= 0 then
 			return false, "not an integer";
 		end
+		if field.range_max and n > field.range_max then
+			return false, "out of bounds";
+		elseif field.range_min and n < field.range_min then
+			return false, "out of bounds";
+		end
 		return true, n;
 	end