Software /
code /
prosody
File
spec/util_datamapper_spec.lua @ 13264:9b720c38fee8
mod_cron: Revert bbd3ac65640d
Maybe it is better to run daily and weekly tasks 'now' on the theory
that people set these things up during times that are appropriate for
maintenance already, so the same time next day or next week might be
fine for periodic cleanup.
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Sun, 30 Jul 2023 13:03:40 +0200 |
parent | 12818:74ed772ff5fb |
line wrap: on
line source
local st local xml local map setup(function() st = require "util.stanza"; xml = require "util.xml"; map = require "util.datamapper"; end); describe("util.datamapper", function() local s, x, d local disco, disco_info, disco_schema setup(function() -- a convenience function for simple attributes, there's a few of them local attr = {["$ref"]="#/$defs/attr"}; s = { ["$defs"] = { attr = { type = "string"; xml = { attribute = true } } }; type = "object"; xml = {name = "message"; namespace = "jabber:client"}; properties = { to = attr; from = attr; type = attr; id = attr; body = true; -- should be assumed to be a string lang = {type = "string"; xml = {attribute = true; prefix = "xml"}}; delay = { type = "object"; xml = {namespace = "urn:xmpp:delay"; name = "delay"}; properties = {stamp = attr; from = attr; reason = {type = "string"; xml = {text = true}}}; }; state = { type = "string"; enum = { "active", "inactive", "gone", "composing", "paused", }; xml = {x_name_is_value = true; namespace = "http://jabber.org/protocol/chatstates"}; }; fallback = { type = "boolean"; xml = {x_name_is_value = true; name = "fallback"; namespace = "urn:xmpp:fallback:0"}; }; origin_id = { type = "string"; xml = {name = "origin-id"; namespace = "urn:xmpp:sid:0"; x_single_attribute = "id"}; }; react = { type = "object"; xml = {namespace = "urn:xmpp:reactions:0"; name = "reactions"}; properties = { to = {type = "string"; xml = {attribute = true; name = "id"}}; -- should be assumed to be array since it has 'items' reactions = { items = { xml = { name = "reaction" } } }; }; }; stanza_ids = { type = "array"; items = { xml = {name = "stanza-id"; namespace = "urn:xmpp:sid:0"}; type = "object"; properties = { id = attr; by = attr; }; }; }; }; }; x = xml.parse [[ <message xmlns="jabber:client" xml:lang="en" to="a@test" from="b@test" type="chat" id="1"> <body>Hello</body> <delay xmlns='urn:xmpp:delay' from='test' stamp='2021-03-07T15:59:08+00:00'>Because</delay> <UNRELATED xmlns='http://jabber.org/protocol/chatstates'/> <active xmlns='http://jabber.org/protocol/chatstates'/> <fallback xmlns='urn:xmpp:fallback:0'/> <origin-id xmlns='urn:xmpp:sid:0' id='qgkmMdPB'/> <stanza-id xmlns='urn:xmpp:sid:0' id='abc1' by='muc'/> <stanza-id xmlns='urn:xmpp:sid:0' id='xyz2' by='host'/> <reactions id='744f6e18-a57a-11e9-a656-4889e7820c76' xmlns='urn:xmpp:reactions:0'> <reaction>👋</reaction> <reaction>🐢</reaction> </reactions> </message> ]]; d = { to = "a@test"; from = "b@test"; type = "chat"; id = "1"; lang = "en"; body = "Hello"; delay = {from = "test"; stamp = "2021-03-07T15:59:08+00:00"; reason = "Because"}; state = "active"; fallback = true; origin_id = "qgkmMdPB"; stanza_ids = {{id = "abc1"; by = "muc"}; {id = "xyz2"; by = "host"}}; react = { to = "744f6e18-a57a-11e9-a656-4889e7820c76"; reactions = { "👋", "🐢", }; }; }; disco_schema = { ["$defs"] = { attr = { type = "string"; xml = { attribute = true } } }; type = "object"; xml = { name = "iq"; namespace = "jabber:client" }; properties = { to = attr; from = attr; type = attr; id = attr; disco = { type = "object"; xml = { name = "query"; namespace = "http://jabber.org/protocol/disco#info" }; properties = { features = { type = "array"; items = { type = "string"; xml = { name = "feature"; x_single_attribute = "var"; }; }; }; }; }; }; }; disco_info = xml.parse[[ <iq type="result" id="disco1" from="example.com"> <query xmlns="http://jabber.org/protocol/disco#info"> <feature var="urn:example:feature:1">wrong</feature> <feature var="urn:example:feature:2"/> <feature var="urn:example:feature:3"/> <unrelated var="urn:example:feature:not"/> </query> </iq> ]]; disco = { type="result"; id="disco1"; from="example.com"; disco = { features = { "urn:example:feature:1"; "urn:example:feature:2"; "urn:example:feature:3"; }; }; }; end); describe("parse", function() it("works", function() assert.same(d, map.parse(s, x)); end); it("handles arrays", function () assert.same(disco, map.parse(disco_schema, disco_info)); end); it("deals with locally built stanzas", function() -- FIXME this could also be argued to be a util.stanza problem local ver_schema = { type = "object"; xml = {name = "iq"}; properties = { type = {type = "string"; xml = {attribute = true}}; id = {type = "string"; xml = {attribute = true}}; version = { type = "object"; xml = {name = "query"; namespace = "jabber:iq:version"}; -- properties should be assumed to be strings properties = {name = true; version = {}; os = {}}; }; }; }; local ver_st = st.iq({type = "result"; id = "v1"}) :query("jabber:iq:version") :text_tag("name", "Prosody") :text_tag("version", "trunk") :text_tag("os", "Lua 5.3") :reset(); local data = {type = "result"; id = "v1"; version = {name = "Prosody"; version = "trunk"; os = "Lua 5.3"}} assert.same(data, map.parse(ver_schema, ver_st)); end); end); describe("unparse", function() it("works", function() local u = map.unparse(s, d); assert.equal("message", u.name); assert.same(x.attr, u.attr); assert.equal(x:get_child_text("body"), u:get_child_text("body")); assert.equal(x:get_child_text("delay", "urn:xmpp:delay"), u:get_child_text("delay", "urn:xmpp:delay")); assert.same(x:get_child("delay", "urn:xmpp:delay").attr, u:get_child("delay", "urn:xmpp:delay").attr); assert.same(x:get_child("origin-id", "urn:xmpp:sid:0").attr, u:get_child("origin-id", "urn:xmpp:sid:0").attr); assert.same(x:get_child("reactions", "urn:xmpp:reactions:0").attr, u:get_child("reactions", "urn:xmpp:reactions:0").attr); assert.same(2, #u:get_child("reactions", "urn:xmpp:reactions:0").tags); for _, tag in ipairs(x.tags) do if tag.name ~= "UNRELATED" then assert.truthy(u:get_child(tag.name, tag.attr.xmlns) or u:get_child(tag.name), tag:top_tag()) end end assert.equal(#x.tags-1, #u.tags) end); it("handles arrays", function () local u = map.unparse(disco_schema, disco); assert.equal("urn:example:feature:1", u:find("{http://jabber.org/protocol/disco#info}query/feature/@var")) local n = 0; for child in u:get_child("query", "http://jabber.org/protocol/disco#info"):childtags("feature") do n = n + 1; assert.equal(string.format("urn:example:feature:%d", n), child.attr.var); end end); end); end)