changeset 854:eac2cc421f49

irccdctl: support origins in rule-edit and rule-add, #947
author David Demelier <markand@malikania.fr>
date Wed, 17 Jul 2019 21:06:43 +0200
parents f3d48aed8cf2
children 199b146e8163
files CHANGES.md irccd-test/main.cpp irccdctl/cli.cpp libirccd-daemon/irccd/daemon/transport_command.cpp tests/src/irccdctl/cli-rule-add/main.cpp tests/src/irccdctl/cli-rule-edit/main.cpp tests/src/irccdctl/cli-rule-info/main.cpp tests/src/irccdctl/cli-rule-list/main.cpp tests/src/irccdctl/cli-rule-move/main.cpp tests/src/irccdctl/cli-rule-remove/main.cpp
diffstat 10 files changed, 218 insertions(+), 126 deletions(-) [+]
line wrap: on
line diff
--- a/CHANGES.md	Wed Jul 17 21:07:43 2019 +0200
+++ b/CHANGES.md	Wed Jul 17 21:06:43 2019 +0200
@@ -19,7 +19,9 @@
 
 irccdctl:
 
-- New option `ipv4` in `[connect]` (#945).
+- New option `ipv4` in `[connect]` (#945),
+- New option `-o` in `rule-add` (#947),
+- New option `-o` and `-O` in `rule-edit` (#947).
 
 irccd-test:
 
--- a/irccd-test/main.cpp	Wed Jul 17 21:07:43 2019 +0200
+++ b/irccd-test/main.cpp	Wed Jul 17 21:06:43 2019 +0200
@@ -655,13 +655,6 @@
 
 	const auto pack = load_cli(argc, argv);
 
-	puts("ARGS");
-	for (const auto& a : std::get<0>(pack))
-		std::cout << a << std::endl;
-	puts("OPTIONS");
-	for (const auto& [k,v] : std::get<1>(pack))
-		std::cout << k << " = " << v << std::endl;
-
 	load_config(pack);
 	load_plugins(pack);
 }
--- a/irccdctl/cli.cpp	Wed Jul 17 21:07:43 2019 +0200
+++ b/irccdctl/cli.cpp	Wed Jul 17 21:06:43 2019 +0200
@@ -462,7 +462,7 @@
 
 void rule_add_cli::exec(ctl::controller& ctl, const std::vector<std::string>& argv)
 {
-	const auto [ args, options ] = options::parse(argv.begin(), argv.end(), "c:e:i:p:s:");
+	const auto [ args, options ] = options::parse(argv.begin(), argv.end(), "c:e:i:o:p:s:");
 
 	if (args.size() < 1U)
 		throw std::invalid_argument("rule-add requires at least 1 argument");
@@ -472,7 +472,8 @@
 		{ "channels",   nlohmann::json::array() },
 		{ "events",     nlohmann::json::array() },
 		{ "plugins",    nlohmann::json::array() },
-		{ "servers",    nlohmann::json::array() }
+		{ "servers",    nlohmann::json::array() },
+		{ "origins",    nlohmann::json::array() }
 	});
 
 	// All sets.
@@ -484,6 +485,9 @@
 		case 'e':
 			json["events"].push_back(value);
 			break;
+		case 'o':
+			json["origins"].push_back(value);
+			break;
 		case 'p':
 			json["plugins"].push_back(value);
 			break;
@@ -516,7 +520,7 @@
 
 void rule_edit_cli::exec(ctl::controller& ctl, const std::vector<std::string>& argv)
 {
-	const auto [ args, options ] = options::parse(argv.begin(), argv.end(), "a:c:C:e:E:p:P:s:S:");
+	const auto [ args, options ] = options::parse(argv.begin(), argv.end(), "a:c:C:e:E:o:O:p:P:s:S:");
 
 	if (args.size() < 1U)
 		throw std::invalid_argument("rule-edit requires at least 1 argument");
@@ -526,7 +530,8 @@
 		{ "channels",   nlohmann::json::array() },
 		{ "events",     nlohmann::json::array() },
 		{ "plugins",    nlohmann::json::array() },
-		{ "servers",    nlohmann::json::array() }
+		{ "servers",    nlohmann::json::array() },
+		{ "origins",    nlohmann::json::array() }
 	});
 
 	for (const auto& [ option, value ] : options) {
@@ -540,6 +545,12 @@
 		case 'e':
 			json["add-events"].push_back(value);
 			break;
+		case 'o':
+			json["add-origins"].push_back(value);
+			break;
+		case 'O':
+			json["remove-origins"].push_back(value);
+			break;
 		case 'p':
 			json["add-plugins"].push_back(value);
 			break;
@@ -600,6 +611,7 @@
 	align("rule:") << index << std::endl;
 	align("servers:") << unjoin(json["servers"]) << std::endl;
 	align("channels:") << unjoin(json["channels"]) << std::endl;
+	align("origins:") << unjoin(json["origins"]) << std::endl;
 	align("plugins:") << unjoin(json["plugins"]) << std::endl;
 	align("events:") << unjoin(json["events"]) << std::endl;
 	align("action:") << unstr(json["action"]) << std::endl;
--- a/libirccd-daemon/irccd/daemon/transport_command.cpp	Wed Jul 17 21:07:43 2019 +0200
+++ b/libirccd-daemon/irccd/daemon/transport_command.cpp	Wed Jul 17 21:06:43 2019 +0200
@@ -311,6 +311,7 @@
 	updateset(rule.events, args, "events");
 	updateset(rule.plugins, args, "plugins");
 	updateset(rule.servers, args, "servers");
+	updateset(rule.origins, args, "origins");
 
 	auto action = args.find("action");
 
--- a/tests/src/irccdctl/cli-rule-add/main.cpp	Wed Jul 17 21:07:43 2019 +0200
+++ b/tests/src/irccdctl/cli-rule-add/main.cpp	Wed Jul 17 21:06:43 2019 +0200
@@ -47,6 +47,7 @@
 			"-e onMessage", "-e onCommand",
 			"-p p1",        "-p p2",
 			"-s s1",        "-s s2",
+			"-o o1",        "-o o2",
 			"drop"
 		});
 
@@ -59,14 +60,15 @@
 		const auto [code, out, err] = exec({ "rule-list" });
 
 		BOOST_TEST(!code);
-		BOOST_TEST(out.size() == 6U);
+		BOOST_TEST(out.size() == 7U);
 		BOOST_TEST(err.size() == 0U);
 		BOOST_TEST(out[0]  == "rule:           0");
 		BOOST_TEST(out[1]  == "servers:        s1 s2 ");
 		BOOST_TEST(out[2]  == "channels:       c1 c2 ");
-		BOOST_TEST(out[3]  == "plugins:        p1 p2 ");
-		BOOST_TEST(out[4]  == "events:         onCommand onMessage ");
-		BOOST_TEST(out[5]  == "action:         drop");
+		BOOST_TEST(out[3]  == "origins:        o1 o2 ");
+		BOOST_TEST(out[4]  == "plugins:        p1 p2 ");
+		BOOST_TEST(out[5]  == "events:         onCommand onMessage ");
+		BOOST_TEST(out[6]  == "action:         drop");
 	}
 }
 
@@ -86,19 +88,20 @@
 		const auto [code, out, err] = exec({ "rule-list" });
 
 		BOOST_TEST(!code);
-		BOOST_TEST(out.size() == 6U);
+		BOOST_TEST(out.size() == 7U);
 		BOOST_TEST(err.size() == 0U);
 		BOOST_TEST(out[0]  == "rule:           0");
 		BOOST_TEST(out[1]  == "servers:        s1 s2 ");
 		BOOST_TEST(out[2]  == "channels:       ");
-		BOOST_TEST(out[3]  == "plugins:        ");
-		BOOST_TEST(out[4]  == "events:         ");
-		BOOST_TEST(out[5]  == "action:         drop");
+		BOOST_TEST(out[3]  == "origins:        ");
+		BOOST_TEST(out[4]  == "plugins:        ");
+		BOOST_TEST(out[5]  == "events:         ");
+		BOOST_TEST(out[6]  == "action:         drop");
 	}
 }
 
 BOOST_AUTO_TEST_CASE(channel)
-	{
+{
 	start();
 
 	{
@@ -113,14 +116,43 @@
 		const auto [code, out, err] = exec({ "rule-list" });
 
 		BOOST_TEST(!code);
-		BOOST_TEST(out.size() == 6U);
+		BOOST_TEST(out.size() == 7U);
 		BOOST_TEST(err.size() == 0U);
 		BOOST_TEST(out[0]  == "rule:           0");
 		BOOST_TEST(out[1]  == "servers:        ");
 		BOOST_TEST(out[2]  == "channels:       c1 c2 ");
-		BOOST_TEST(out[3]  == "plugins:        ");
-		BOOST_TEST(out[4]  == "events:         ");
-		BOOST_TEST(out[5]  == "action:         drop");
+		BOOST_TEST(out[3]  == "origins:        ");
+		BOOST_TEST(out[4]  == "plugins:        ");
+		BOOST_TEST(out[5]  == "events:         ");
+		BOOST_TEST(out[6]  == "action:         drop");
+	}
+}
+
+BOOST_AUTO_TEST_CASE(origin)
+{
+	start();
+
+	{
+		const auto [code, out, err] = exec({ "rule-add", "-o c1", "-o c2", "drop" });
+
+		BOOST_TEST(!code);
+		BOOST_TEST(out.size() == 0U);
+		BOOST_TEST(err.size() == 0U);
+	}
+
+	{
+		const auto [code, out, err] = exec({ "rule-list" });
+
+		BOOST_TEST(!code);
+		BOOST_TEST(out.size() == 7U);
+		BOOST_TEST(err.size() == 0U);
+		BOOST_TEST(out[0]  == "rule:           0");
+		BOOST_TEST(out[1]  == "servers:        ");
+		BOOST_TEST(out[2]  == "channels:       ");
+		BOOST_TEST(out[3]  == "origins:        o1 o2 ");
+		BOOST_TEST(out[4]  == "plugins:        ");
+		BOOST_TEST(out[5]  == "events:         ");
+		BOOST_TEST(out[6]  == "action:         drop");
 	}
 }
 
@@ -140,14 +172,15 @@
 		const auto [code, out, err] = exec({ "rule-list" });
 
 		BOOST_TEST(!code);
-		BOOST_TEST(out.size() == 6U);
+		BOOST_TEST(out.size() == 7U);
 		BOOST_TEST(err.size() == 0U);
 		BOOST_TEST(out[0]  == "rule:           0");
 		BOOST_TEST(out[1]  == "servers:        ");
 		BOOST_TEST(out[2]  == "channels:       ");
-		BOOST_TEST(out[3]  == "plugins:        p1 p2 ");
-		BOOST_TEST(out[4]  == "events:         ");
-		BOOST_TEST(out[5]  == "action:         drop");
+		BOOST_TEST(out[3]  == "origins:        ");
+		BOOST_TEST(out[4]  == "plugins:        p1 p2 ");
+		BOOST_TEST(out[5]  == "events:         ");
+		BOOST_TEST(out[6]  == "action:         drop");
 	}
 }
 
@@ -167,14 +200,15 @@
 		const auto [code, out, err] = exec({ "rule-list" });
 
 		BOOST_TEST(!code);
-		BOOST_TEST(out.size() == 6U);
+		BOOST_TEST(out.size() == 7U);
 		BOOST_TEST(err.size() == 0U);
 		BOOST_TEST(out[0]  == "rule:           0");
 		BOOST_TEST(out[1]  == "servers:        ");
 		BOOST_TEST(out[2]  == "channels:       ");
-		BOOST_TEST(out[3]  == "plugins:        ");
-		BOOST_TEST(out[4]  == "events:         onCommand onMessage ");
-		BOOST_TEST(out[5]  == "action:         drop");
+		BOOST_TEST(out[3]  == "origins:        ");
+		BOOST_TEST(out[4]  == "plugins:        ");
+		BOOST_TEST(out[5]  == "events:         onCommand onMessage ");
+		BOOST_TEST(out[6]  == "action:         drop");
 	}
 }
 
--- a/tests/src/irccdctl/cli-rule-edit/main.cpp	Wed Jul 17 21:07:43 2019 +0200
+++ b/tests/src/irccdctl/cli-rule-edit/main.cpp	Wed Jul 17 21:06:43 2019 +0200
@@ -67,14 +67,15 @@
 		const auto [code, out, err] = exec({ "rule-list" });
 
 		BOOST_TEST(!code);
-		BOOST_TEST(out.size() == 6U);
+		BOOST_TEST(out.size() == 7U);
 		BOOST_TEST(err.size() == 0U);
 		BOOST_TEST(out[0]  == "rule:           0");
 		BOOST_TEST(out[1]  == "servers:        ts1 ts2 ");
 		BOOST_TEST(out[2]  == "channels:       c1 c2 ");
-		BOOST_TEST(out[3]  == "plugins:        p1 p2 ");
-		BOOST_TEST(out[4]  == "events:         onCommand onMessage ");
-		BOOST_TEST(out[5]  == "action:         drop");
+		BOOST_TEST(out[3]  == "origins:        o1 o2 ");
+		BOOST_TEST(out[4]  == "plugins:        p1 p2 ");
+		BOOST_TEST(out[5]  == "events:         onCommand onMessage ");
+		BOOST_TEST(out[6]  == "action:         drop");
 	}
 }
 
@@ -98,14 +99,47 @@
 		const auto [code, out, err] = exec({ "rule-list" });
 
 		BOOST_TEST(!code);
-		BOOST_TEST(out.size() == 6U);
+		BOOST_TEST(out.size() == 7U);
 		BOOST_TEST(err.size() == 0U);
 		BOOST_TEST(out[0]  == "rule:           0");
 		BOOST_TEST(out[1]  == "servers:        s1 s2 ");
 		BOOST_TEST(out[2]  == "channels:       tc1 tc2 ");
-		BOOST_TEST(out[3]  == "plugins:        p1 p2 ");
-		BOOST_TEST(out[4]  == "events:         onCommand onMessage ");
-		BOOST_TEST(out[5]  == "action:         drop");
+		BOOST_TEST(out[3]  == "origins:        o1 o2 ");
+		BOOST_TEST(out[4]  == "plugins:        p1 p2 ");
+		BOOST_TEST(out[5]  == "events:         onCommand onMessage ");
+		BOOST_TEST(out[6]  == "action:         drop");
+	}
+}
+
+BOOST_AUTO_TEST_CASE(origin)
+{
+	start();
+
+	{
+		const auto [code, out, err] = exec({ "rule-edit",
+			"-o to1",   "-o to2",
+			"-O o1",    "-O o2",
+			"0"
+		});
+
+		BOOST_TEST(!code);
+		BOOST_TEST(out.size() == 0U);
+		BOOST_TEST(err.size() == 0U);
+	}
+
+	{
+		const auto [code, out, err] = exec({ "rule-list" });
+
+		BOOST_TEST(!code);
+		BOOST_TEST(out.size() == 7U);
+		BOOST_TEST(err.size() == 0U);
+		BOOST_TEST(out[0]  == "rule:           0");
+		BOOST_TEST(out[1]  == "servers:        s1 s2 ");
+		BOOST_TEST(out[2]  == "channels:       c1 c2 ");
+		BOOST_TEST(out[3]  == "origins:        to1 to2 ");
+		BOOST_TEST(out[4]  == "plugins:        p1 p2 ");
+		BOOST_TEST(out[5]  == "events:         onCommand onMessage ");
+		BOOST_TEST(out[6]  == "action:         drop");
 	}
 }
 
@@ -129,14 +163,15 @@
 		const auto [code, out, err] = exec({ "rule-list" });
 
 		BOOST_TEST(!code);
-		BOOST_TEST(out.size() == 6U);
+		BOOST_TEST(out.size() == 7U);
 		BOOST_TEST(err.size() == 0U);
 		BOOST_TEST(out[0]  == "rule:           0");
 		BOOST_TEST(out[1]  == "servers:        s1 s2 ");
 		BOOST_TEST(out[2]  == "channels:       c1 c2 ");
-		BOOST_TEST(out[3]  == "plugins:        tp1 tp2 ");
-		BOOST_TEST(out[4]  == "events:         onCommand onMessage ");
-		BOOST_TEST(out[5]  == "action:         drop");
+		BOOST_TEST(out[3]  == "origins:        o1 o2 ");
+		BOOST_TEST(out[4]  == "plugins:        tp1 tp2 ");
+		BOOST_TEST(out[5]  == "events:         onCommand onMessage ");
+		BOOST_TEST(out[6]  == "action:         drop");
 	}
 }
 
@@ -160,14 +195,15 @@
 		const auto [code, out, err] = exec({ "rule-list" });
 
 		BOOST_TEST(!code);
-		BOOST_TEST(out.size() == 6U);
+		BOOST_TEST(out.size() == 7U);
 		BOOST_TEST(err.size() == 0U);
 		BOOST_TEST(out[0]  == "rule:           0");
 		BOOST_TEST(out[1]  == "servers:        s1 s2 ");
 		BOOST_TEST(out[2]  == "channels:       c1 c2 ");
-		BOOST_TEST(out[3]  == "plugins:        p1 p2 ");
-		BOOST_TEST(out[4]  == "events:         onKick onNickname ");
-		BOOST_TEST(out[5]  == "action:         drop");
+		BOOST_TEST(out[3]  == "origins:        o1 o2 ");
+		BOOST_TEST(out[4]  == "plugins:        p1 p2 ");
+		BOOST_TEST(out[5]  == "events:         onKick onNickname ");
+		BOOST_TEST(out[6]  == "action:         drop");
 	}
 }
 
@@ -187,14 +223,15 @@
 		const auto [code, out, err] = exec({ "rule-list" });
 
 		BOOST_TEST(!code);
-		BOOST_TEST(out.size() == 6U);
+		BOOST_TEST(out.size() == 7U);
 		BOOST_TEST(err.size() == 0U);
 		BOOST_TEST(out[0]  == "rule:           0");
 		BOOST_TEST(out[1]  == "servers:        s1 s2 ");
 		BOOST_TEST(out[2]  == "channels:       c1 c2 ");
-		BOOST_TEST(out[3]  == "plugins:        p1 p2 ");
-		BOOST_TEST(out[4]  == "events:         onCommand onMessage ");
-		BOOST_TEST(out[5]  == "action:         accept");
+		BOOST_TEST(out[3]  == "origins:        o1 o2 ");
+		BOOST_TEST(out[4]  == "plugins:        p1 p2 ");
+		BOOST_TEST(out[5]  == "events:         onCommand onMessage ");
+		BOOST_TEST(out[6]  == "action:         accept");
 	}
 }
 
--- a/tests/src/irccdctl/cli-rule-info/main.cpp	Wed Jul 17 21:07:43 2019 +0200
+++ b/tests/src/irccdctl/cli-rule-info/main.cpp	Wed Jul 17 21:06:43 2019 +0200
@@ -54,14 +54,15 @@
 	const auto [code, out, err] = exec({ "rule-info", "0" });
 
 	BOOST_TEST(!code);
-	BOOST_TEST(out.size() == 6U);
+	BOOST_TEST(out.size() == 7U);
 	BOOST_TEST(err.size() == 0U);
 	BOOST_TEST(out[0]  == "rule:           0");
 	BOOST_TEST(out[1]  == "servers:        s1 s2 ");
 	BOOST_TEST(out[2]  == "channels:       c1 c2 ");
-	BOOST_TEST(out[3]  == "plugins:        p1 p2 ");
-	BOOST_TEST(out[4]  == "events:         onCommand onMessage ");
-	BOOST_TEST(out[5]  == "action:         drop");
+	BOOST_TEST(out[3]  == "origins:        o1 o2 ");
+	BOOST_TEST(out[4]  == "plugins:        p1 p2 ");
+	BOOST_TEST(out[5]  == "events:         onCommand onMessage ");
+	BOOST_TEST(out[6]  == "action:         drop");
 }
 
 BOOST_AUTO_TEST_SUITE(errors)
--- a/tests/src/irccdctl/cli-rule-list/main.cpp	Wed Jul 17 21:07:43 2019 +0200
+++ b/tests/src/irccdctl/cli-rule-list/main.cpp	Wed Jul 17 21:06:43 2019 +0200
@@ -54,14 +54,15 @@
 	const auto [code, out, err] = exec({ "rule-list" });
 
 	BOOST_TEST(!code);
-	BOOST_TEST(out.size() == 6U);
+	BOOST_TEST(out.size() == 7U);
 	BOOST_TEST(err.size() == 0U);
 	BOOST_TEST(out[0]  == "rule:           0");
 	BOOST_TEST(out[1]  == "servers:        s1 s2 ");
 	BOOST_TEST(out[2]  == "channels:       c1 c2 ");
-	BOOST_TEST(out[3]  == "plugins:        p1 p2 ");
-	BOOST_TEST(out[4]  == "events:         onCommand onMessage ");
-	BOOST_TEST(out[5]  == "action:         drop");
+	BOOST_TEST(out[3]  == "origins:        o1 o2 ");
+	BOOST_TEST(out[4]  == "plugins:        p1 p2 ");
+	BOOST_TEST(out[5]  == "events:         onCommand onMessage ");
+	BOOST_TEST(out[6]  == "action:         drop");
 }
 
 BOOST_AUTO_TEST_SUITE_END()
--- a/tests/src/irccdctl/cli-rule-move/main.cpp	Wed Jul 17 21:07:43 2019 +0200
+++ b/tests/src/irccdctl/cli-rule-move/main.cpp	Wed Jul 17 21:06:43 2019 +0200
@@ -79,28 +79,31 @@
 		const auto [code, out, err] = exec({ "rule-list" });
 
 		BOOST_TEST(!code);
-		BOOST_TEST(out.size() == 20U);
+		BOOST_TEST(out.size() == 23U);
 		BOOST_TEST(err.size() == 0U);
 		BOOST_TEST(out[0]  == "rule:           0");
 		BOOST_TEST(out[1]  == "servers:        s2 ");
 		BOOST_TEST(out[2]  == "channels:       c2 ");
-		BOOST_TEST(out[3]  == "plugins:        p2 ");
-		BOOST_TEST(out[4]  == "events:         onCommand ");
-		BOOST_TEST(out[5]  == "action:         drop");
-		BOOST_TEST(out[6]  == "");
-		BOOST_TEST(out[7]  == "rule:           1");
-		BOOST_TEST(out[8]  == "servers:        s1 ");
-		BOOST_TEST(out[9]  == "channels:       c1 ");
-		BOOST_TEST(out[10] == "plugins:        p1 ");
-		BOOST_TEST(out[11] == "events:         onTopic ");
-		BOOST_TEST(out[12] == "action:         accept");
-		BOOST_TEST(out[13] == "");
-		BOOST_TEST(out[14] == "rule:           2");
-		BOOST_TEST(out[15] == "servers:        s3 ");
-		BOOST_TEST(out[16] == "channels:       c3 ");
-		BOOST_TEST(out[17] == "plugins:        p3 ");
-		BOOST_TEST(out[18] == "events:         onMessage ");
-		BOOST_TEST(out[19] == "action:         accept");
+		BOOST_TEST(out[3]  == "origins:        o2 ");
+		BOOST_TEST(out[4]  == "plugins:        p2 ");
+		BOOST_TEST(out[5]  == "events:         onCommand ");
+		BOOST_TEST(out[6]  == "action:         drop");
+		BOOST_TEST(out[7]  == "");
+		BOOST_TEST(out[8]  == "rule:           1");
+		BOOST_TEST(out[9]  == "servers:        s1 ");
+		BOOST_TEST(out[10] == "channels:       c1 ");
+		BOOST_TEST(out[11] == "origins:        o1 ");
+		BOOST_TEST(out[12] == "plugins:        p1 ");
+		BOOST_TEST(out[13] == "events:         onTopic ");
+		BOOST_TEST(out[14] == "action:         accept");
+		BOOST_TEST(out[15] == "");
+		BOOST_TEST(out[16] == "rule:           2");
+		BOOST_TEST(out[17] == "servers:        s3 ");
+		BOOST_TEST(out[18] == "channels:       c3 ");
+		BOOST_TEST(out[19] == "origins:        o3 ");
+		BOOST_TEST(out[20] == "plugins:        p3 ");
+		BOOST_TEST(out[21] == "events:         onMessage ");
+		BOOST_TEST(out[22] == "action:         accept");
 	}
 }
 
@@ -120,28 +123,31 @@
 		const auto [code, out, err] = exec({ "rule-list" });
 
 		BOOST_TEST(!code);
-		BOOST_TEST(out.size() == 20U);
+		BOOST_TEST(out.size() == 23U);
 		BOOST_TEST(err.size() == 0U);
 		BOOST_TEST(out[0]  == "rule:           0");
 		BOOST_TEST(out[1]  == "servers:        s3 ");
 		BOOST_TEST(out[2]  == "channels:       c3 ");
-		BOOST_TEST(out[3]  == "plugins:        p3 ");
-		BOOST_TEST(out[4]  == "events:         onMessage ");
-		BOOST_TEST(out[5]  == "action:         accept");
-		BOOST_TEST(out[6]  == "");
-		BOOST_TEST(out[7]  == "rule:           1");
-		BOOST_TEST(out[8]  == "servers:        s1 ");
-		BOOST_TEST(out[9]  == "channels:       c1 ");
-		BOOST_TEST(out[10] == "plugins:        p1 ");
-		BOOST_TEST(out[11] == "events:         onTopic ");
-		BOOST_TEST(out[12] == "action:         accept");
-		BOOST_TEST(out[13] == "");
-		BOOST_TEST(out[14] == "rule:           2");
-		BOOST_TEST(out[15] == "servers:        s2 ");
-		BOOST_TEST(out[16] == "channels:       c2 ");
-		BOOST_TEST(out[17] == "plugins:        p2 ");
-		BOOST_TEST(out[18] == "events:         onCommand ");
-		BOOST_TEST(out[19] == "action:         drop");
+		BOOST_TEST(out[3]  == "origins:        o3 ");
+		BOOST_TEST(out[4]  == "plugins:        p3 ");
+		BOOST_TEST(out[5]  == "events:         onMessage ");
+		BOOST_TEST(out[6]  == "action:         accept");
+		BOOST_TEST(out[7]  == "");
+		BOOST_TEST(out[8]  == "rule:           1");
+		BOOST_TEST(out[9]  == "servers:        s1 ");
+		BOOST_TEST(out[10] == "channels:       c1 ");
+		BOOST_TEST(out[11] == "origins:        o1 ");
+		BOOST_TEST(out[12] == "plugins:        p1 ");
+		BOOST_TEST(out[13] == "events:         onTopic ");
+		BOOST_TEST(out[14] == "action:         accept");
+		BOOST_TEST(out[15] == "");
+		BOOST_TEST(out[16] == "rule:           2");
+		BOOST_TEST(out[17] == "servers:        s2 ");
+		BOOST_TEST(out[18] == "channels:       c2 ");
+		BOOST_TEST(out[19] == "origins:        o2 ");
+		BOOST_TEST(out[20] == "plugins:        p2 ");
+		BOOST_TEST(out[21] == "events:         onCommand ");
+		BOOST_TEST(out[22] == "action:         drop");
 	}
 }
 
@@ -161,28 +167,31 @@
 		const auto [code, out, err] = exec({ "rule-list" });
 
 		BOOST_TEST(!code);
-		BOOST_TEST(out.size() == 20U);
+		BOOST_TEST(out.size() == 23U);
 		BOOST_TEST(err.size() == 0U);
 		BOOST_TEST(out[0]  == "rule:           0");
 		BOOST_TEST(out[1]  == "servers:        s1 ");
 		BOOST_TEST(out[2]  == "channels:       c1 ");
-		BOOST_TEST(out[3]  == "plugins:        p1 ");
-		BOOST_TEST(out[4]  == "events:         onTopic ");
-		BOOST_TEST(out[5]  == "action:         accept");
-		BOOST_TEST(out[6]  == "");
-		BOOST_TEST(out[7]  == "rule:           1");
-		BOOST_TEST(out[8]  == "servers:        s2 ");
-		BOOST_TEST(out[9]  == "channels:       c2 ");
-		BOOST_TEST(out[10] == "plugins:        p2 ");
-		BOOST_TEST(out[11] == "events:         onCommand ");
-		BOOST_TEST(out[12] == "action:         drop");
-		BOOST_TEST(out[13] == "");
-		BOOST_TEST(out[14] == "rule:           2");
-		BOOST_TEST(out[15] == "servers:        s3 ");
-		BOOST_TEST(out[16] == "channels:       c3 ");
-		BOOST_TEST(out[17] == "plugins:        p3 ");
-		BOOST_TEST(out[18] == "events:         onMessage ");
-		BOOST_TEST(out[19] == "action:         accept");
+		BOOST_TEST(out[3] == "origins:        o1 ");
+		BOOST_TEST(out[4]  == "plugins:        p1 ");
+		BOOST_TEST(out[5]  == "events:         onTopic ");
+		BOOST_TEST(out[6]  == "action:         accept");
+		BOOST_TEST(out[7]  == "");
+		BOOST_TEST(out[8]  == "rule:           1");
+		BOOST_TEST(out[9]  == "servers:        s2 ");
+		BOOST_TEST(out[10]  == "channels:       c2 ");
+		BOOST_TEST(out[11] == "origins:        o2 ");
+		BOOST_TEST(out[12] == "plugins:        p2 ");
+		BOOST_TEST(out[13] == "events:         onCommand ");
+		BOOST_TEST(out[14] == "action:         drop");
+		BOOST_TEST(out[15] == "");
+		BOOST_TEST(out[16] == "rule:           2");
+		BOOST_TEST(out[17] == "servers:        s3 ");
+		BOOST_TEST(out[18] == "channels:       c3 ");
+		BOOST_TEST(out[19] == "origins:        o3 ");
+		BOOST_TEST(out[20] == "plugins:        p3 ");
+		BOOST_TEST(out[21] == "events:         onMessage ");
+		BOOST_TEST(out[22] == "action:         accept");
 	}
 }
 
--- a/tests/src/irccdctl/cli-rule-remove/main.cpp	Wed Jul 17 21:07:43 2019 +0200
+++ b/tests/src/irccdctl/cli-rule-remove/main.cpp	Wed Jul 17 21:06:43 2019 +0200
@@ -79,21 +79,23 @@
 		const auto [code, out, err] = exec({ "rule-list" });
 
 		BOOST_TEST(!code);
-		BOOST_TEST(out.size() == 13U);
+		BOOST_TEST(out.size() == 15U);
 		BOOST_TEST(err.size() == 0U);
 		BOOST_TEST(out[0]  == "rule:           0");
 		BOOST_TEST(out[1]  == "servers:        s2 ");
 		BOOST_TEST(out[2]  == "channels:       c2 ");
-		BOOST_TEST(out[3]  == "plugins:        p2 ");
-		BOOST_TEST(out[4]  == "events:         onCommand ");
-		BOOST_TEST(out[5]  == "action:         drop");
-		BOOST_TEST(out[6]  == "");
-		BOOST_TEST(out[7]  == "rule:           1");
-		BOOST_TEST(out[8]  == "servers:        s3 ");
-		BOOST_TEST(out[9]  == "channels:       c3 ");
-		BOOST_TEST(out[10] == "plugins:        p3 ");
-		BOOST_TEST(out[11] == "events:         onMessage ");
-		BOOST_TEST(out[12] == "action:         accept");
+		BOOST_TEST(out[3]  == "origins:        o2 ");
+		BOOST_TEST(out[4]  == "plugins:        p2 ");
+		BOOST_TEST(out[5]  == "events:         onCommand ");
+		BOOST_TEST(out[6]  == "action:         drop");
+		BOOST_TEST(out[7]  == "");
+		BOOST_TEST(out[8]  == "rule:           1");
+		BOOST_TEST(out[9]  == "servers:        s3 ");
+		BOOST_TEST(out[10] == "channels:       c3 ");
+		BOOST_TEST(out[11] == "origins:        o3 ");
+		BOOST_TEST(out[12] == "plugins:        p3 ");
+		BOOST_TEST(out[13] == "events:         onMessage ");
+		BOOST_TEST(out[14] == "action:         accept");
 	}
 }