3 pubsub
= require
"util.pubsub";
9 auto-create/auto-subscribe
11 resize on max_items change
12 service creation config provides alternative node_defaults
16 describe("util.pubsub", function ()
17 describe("simple node creation and deletion", function ()
18 randomize(false); -- These tests are ordered
20 -- Roughly a port of scansion/scripts/pubsub_createdelete.scs
21 local service
= pubsub
.new();
23 describe("#create", function ()
24 randomize(false); -- These tests are ordered
25 it("creates a new node", function ()
26 assert.truthy(service
:create("princely_musings", true));
29 it("fails to create the same node again", function ()
30 assert.falsy(service
:create("princely_musings", true));
34 describe("#delete", function ()
35 randomize(false); -- These tests are ordered
36 it("deletes the node", function ()
37 assert.truthy(service
:delete("princely_musings", true));
40 it("can't delete an already deleted node", function ()
41 assert.falsy(service
:delete("princely_musings", true));
46 describe("simple publishing", function ()
47 randomize(false); -- These tests are ordered
50 local broadcaster
= spy
.new(function (notif_type
, node_name
, subscribers
, item
) -- luacheck: ignore 212
51 notified
= subscribers
;
53 local service
= pubsub
.new({
54 broadcaster
= broadcaster
;
57 it("creates a node", function ()
58 assert.truthy(service
:create("node", true));
61 it("lets someone subscribe", function ()
62 assert.truthy(service
:add_subscription("node", true, "someone"));
65 it("publishes an item", function ()
66 assert.truthy(service
:publish("node", true, "1", "item 1"));
67 assert.truthy(notified
["someone"]);
70 it("called the broadcaster", function ()
71 assert.spy(broadcaster
).was_called();
74 it("should return one item", function ()
75 local ok
, ret
= service
:get_items("node", true);
77 assert.same({ "1", ["1"] = "item 1" }, ret
);
80 it("lets someone unsubscribe", function ()
81 assert.truthy(service
:remove_subscription("node", true, "someone"));
84 it("does not send notifications after subscription is removed", function ()
85 assert.truthy(service
:publish("node", true, "1", "item 1"));
86 assert.is_nil(notified
["someone"]);
90 describe("publish with config", function ()
91 randomize(false); -- These tests are ordered
93 local broadcaster
= spy
.new(function (notif_type
, node_name
, subscribers
, item
) -- luacheck: ignore 212
95 local service
= pubsub
.new({
96 broadcaster
= broadcaster
;
97 autocreate_on_publish
= true;
100 it("automatically creates node with requested config", function ()
101 assert(service
:publish("node", true, "1", "item 1", { myoption
= true }));
103 local ok
, config
= assert(service
:get_node_config("node", true));
104 assert.equals(true, config
.myoption
);
107 it("fails to publish to a node with differing config", function ()
108 local ok
, err
= service
:publish("node", true, "1", "item 2", { myoption
= false });
110 assert.equals("precondition-not-met", err
);
113 it("allows to publish to a node with differing config when only defaults are suggested", function ()
114 assert(service
:publish("node", true, "1", "item 2", { _defaults_only
= true, myoption
= false }));
118 describe("#issue1082", function ()
119 randomize(false); -- These tests are ordered
121 local service
= pubsub
.new();
123 it("creates a node with max_items = 1", function ()
124 assert.truthy(service
:create("node", true, { max_items
= 1 }));
127 it("changes max_items to 2", function ()
128 assert.truthy(service
:set_node_config("node", true, { max_items
= 2 }));
131 it("publishes one item", function ()
132 assert.truthy(service
:publish("node", true, "1", "item 1"));
135 it("should return one item", function ()
136 local ok
, ret
= service
:get_items("node", true);
138 assert.same({ "1", ["1"] = "item 1" }, ret
);
141 it("publishes another item", function ()
142 assert.truthy(service
:publish("node", true, "2", "item 2"));
145 it("should return two items", function ()
146 local ok
, ret
= service
:get_items("node", true);
156 it("publishes yet another item", function ()
157 assert.truthy(service
:publish("node", true, "3", "item 3"));
160 it("should still return only two items", function ()
161 local ok
, ret
= service
:get_items("node", true);
173 describe("the thing", function ()
174 randomize(false); -- These tests are ordered
176 local service
= pubsub
.new();
178 it("creates a node with some items", function ()
179 assert.truthy(service
:create("node", true, { max_items
= 3 }));
180 assert.truthy(service
:publish("node", true, "1", "item 1"));
181 assert.truthy(service
:publish("node", true, "2", "item 2"));
182 assert.truthy(service
:publish("node", true, "3", "item 3"));
185 it("should return the requested item", function ()
186 local ok
, ret
= service
:get_items("node", true, "1");
188 assert.same({ "1", ["1"] = "item 1" }, ret
);
191 it("should return multiple requested items", function ()
192 local ok
, ret
= service
:get_items("node", true, { "1", "2" });
204 describe("node config", function ()
206 before_each(function ()
207 service
= pubsub
.new();
208 service
:create("test", true);
210 it("access is forbidden for unaffiliated entities", function ()
211 local ok
, err
= service
:get_node_config("test", "stranger");
213 assert.equals("forbidden", err
);
215 it("returns an error for nodes that do not exist", function ()
216 local ok
, err
= service
:get_node_config("nonexistent", true);
218 assert.equals("item-not-found", err
);
222 describe("access model", function ()
223 describe("open", function ()
225 before_each(function ()
226 service
= pubsub
.new();
227 -- Do not supply any config, 'open' should be default
228 service
:create("test", true);
230 it("should be the default", function ()
231 local ok
, config
= service
:get_node_config("test", true);
232 assert.equal("open", config
.access_model
);
234 it("should allow anyone to subscribe", function ()
235 local ok
= service
:add_subscription("test", "stranger", "stranger");
238 it("should still reject outcast-affiliated entities", function ()
239 assert(service
:set_affiliation("test", true, "enemy", "outcast"));
240 local ok
, err
= service
:add_subscription("test", "enemy", "enemy");
242 assert.equal("forbidden", err
);
245 describe("whitelist", function ()
247 before_each(function ()
248 service
= assert(pubsub
.new());
249 assert.is_true(service
:create("test", true, { access_model
= "whitelist" }));
251 it("should be present in the configuration", function ()
252 local ok
, config
= service
:get_node_config("test", true);
253 assert.equal("whitelist", config
.access_model
);
255 it("should not allow anyone to subscribe", function ()
256 local ok
, err
= service
:add_subscription("test", "stranger", "stranger");
258 assert.equals("forbidden", err
);
261 describe("change", function ()
263 before_each(function ()
264 service
= pubsub
.new();
265 service
:create("test", true, { access_model
= "open" });
267 it("affects existing subscriptions", function ()
269 local ok
= service
:add_subscription("test", "stranger", "stranger");
273 local ok
, sub
= service
:get_subscription("test", "stranger", "stranger");
277 assert(service
:set_node_config("test", true, { access_model
= "whitelist" }));
279 local ok
, sub
= service
:get_subscription("test", "stranger", "stranger");
287 describe("publish model", function ()
288 describe("publishers", function ()
290 before_each(function ()
291 service
= pubsub
.new();
292 -- Do not supply any config, 'publishers' should be default
293 service
:create("test", true);
295 it("should be the default", function ()
296 local ok
, config
= service
:get_node_config("test", true);
297 assert.equal("publishers", config
.publish_model
);
299 it("should not allow anyone to publish", function ()
300 assert.is_true(service
:add_subscription("test", "stranger", "stranger"));
301 local ok
, err
= service
:publish("test", "stranger", "item1", "foo");
303 assert.equals("forbidden", err
);
305 it("should allow publishers to publish", function ()
306 assert(service
:set_affiliation("test", true, "mypublisher", "publisher"));
307 local ok
, err
= service
:publish("test", "mypublisher", "item1", "foo");
310 it("should allow owners to publish", function ()
311 assert(service
:set_affiliation("test", true, "myowner", "owner"));
312 local ok
= service
:publish("test", "myowner", "item1", "foo");
316 describe("open", function ()
318 before_each(function ()
319 service
= pubsub
.new();
320 service
:create("test", true, { publish_model
= "open" });
322 it("should allow anyone to publish", function ()
323 local ok
= service
:publish("test", "stranger", "item1", "foo");
327 describe("subscribers", function ()
329 before_each(function ()
330 service
= pubsub
.new();
331 service
:create("test", true, { publish_model
= "subscribers" });
333 it("should not allow non-subscribers to publish", function ()
334 local ok
, err
= service
:publish("test", "stranger", "item1", "foo");
336 assert.equals("forbidden", err
);
338 it("should allow subscribers to publish without an affiliation", function ()
339 assert.is_true(service
:add_subscription("test", "stranger", "stranger"));
340 local ok
= service
:publish("test", "stranger", "item1", "foo");
343 it("should allow publishers to publish without a subscription", function ()
344 assert(service
:set_affiliation("test", true, "mypublisher", "publisher"));
345 local ok
, err
= service
:publish("test", "mypublisher", "item1", "foo");
348 it("should allow owners to publish without a subscription", function ()
349 assert(service
:set_affiliation("test", true, "myowner", "owner"));
350 local ok
= service
:publish("test", "myowner", "item1", "foo");
356 describe("item API", function ()
358 before_each(function ()
359 service
= pubsub
.new();
360 service
:create("test", true, { publish_model
= "subscribers" });
362 describe("get_last_item()", function ()
363 it("succeeds with nil on empty nodes", function ()
364 local ok
, id
, item
= service
:get_last_item("test", true);
369 it("succeeds and returns the last item", function ()
370 service
:publish("test", true, "one", "hello world");
371 service
:publish("test", true, "two", "hello again");
372 service
:publish("test", true, "three", "hey");
373 service
:publish("test", true, "one", "bye");
374 local ok
, id
, item
= service
:get_last_item("test", true);
376 assert.equal("one", id
);
377 assert.equal("bye", item
);
380 describe("get_items()", function ()
381 it("fails on non-existent nodes", function ()
382 local ok
, err
= service
:get_items("no-node", true);
384 assert.equal("item-not-found", err
);
386 it("returns no items on an empty node", function ()
387 local ok
, items
= service
:get_items("test", true);
389 assert.equal(0, #items
);
390 assert.is_nil(next(items
));
392 it("returns no items on an empty node", function ()
393 local ok
, items
= service
:get_items("test", true);
395 assert.equal(0, #items
);
396 assert.is_nil((next(items
)));
398 it("returns all published items", function ()
399 service
:publish("test", true, "one", "hello world");
400 service
:publish("test", true, "two", "hello again");
401 service
:publish("test", true, "three", "hey");
402 service
:publish("test", true, "one", "bye");
403 local ok
, items
= service
:get_items("test", true);
405 assert.same({ "one", "three", "two", two
= "hello again", three
= "hey", one
= "bye" }, items
);
410 describe("restoring data from nodestore", function ()
423 function nodestore
:users()
424 return pairs(self
.data
)
426 function nodestore
:get(key
)
427 return self
.data
[key
];
429 local service
= pubsub
.new({
430 nodestore
= nodestore
;
432 it("subscriptions", function ()
433 local ok
, ret
= service
:get_subscriptions(nil, true, nil)
435 assert.same({ { node
= "test", jid
= "someone", subscription
= true, } }, ret
);
439 describe("node config checking", function ()
441 before_each(function ()
442 service
= pubsub
.new({
443 check_node_config
= function (node
, actor
, config
) -- luacheck: ignore 212
444 return config
["max_items"] <= 20;
449 it("defaults, then configure", function ()
450 local ok
, err
= service
:create("node", true);
451 assert.is_true(ok
, err
);
453 local ok
, err
= service
:set_node_config("node", true, { max_items
= 10 });
454 assert.is_true(ok
, err
);
456 local ok
, err
= service
:set_node_config("node", true, { max_items
= 100 });
457 assert.falsy(ok
, err
);
458 assert.equals(err
, "not-acceptable");
461 it("create with ok config, then configure", function ()
462 local ok
, err
= service
:create("node", true, { max_items
= 10 });
463 assert.is_true(ok
, err
);
465 local ok
, err
= service
:set_node_config("node", true, { max_items
= 100 });
466 assert.falsy(ok
, err
);
468 local ok
, err
= service
:set_node_config("node", true, { max_items
= 10 });
469 assert.is_true(ok
, err
);
472 it("create with unacceptable config", function ()
473 local ok
, err
= service
:create("node", true, { max_items
= 100 });
474 assert.falsy(ok
, err
);