Mercurial > irccd
changeset 450:c8c68d4bf555
Irccdctl: implement rule-remove
author | David Demelier <markand@malikania.fr> |
---|---|
date | Fri, 07 Jul 2017 12:22:17 +0200 |
parents | 9968eac538e6 |
children | 1fdedd2977d2 |
files | doc/html/CMakeLists.txt doc/html/irccdctl/command/index.md doc/html/irccdctl/command/rule-remove.md irccd/main.cpp irccdctl/cli.cpp irccdctl/cli.hpp irccdctl/main.cpp libirccd/irccd/command.cpp libirccd/irccd/command.hpp tests/CMakeLists.txt tests/cmd-rule-remove/CMakeLists.txt tests/cmd-rule-remove/main.cpp |
diffstat | 12 files changed, 282 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/doc/html/CMakeLists.txt Thu Jul 06 12:48:58 2017 +0200 +++ b/doc/html/CMakeLists.txt Fri Jul 07 12:22:17 2017 +0200 @@ -154,6 +154,7 @@ ${html_SOURCE_DIR}/irccdctl/command/plugin-unload.md ${html_SOURCE_DIR}/irccdctl/command/rule-list.md ${html_SOURCE_DIR}/irccdctl/command/rule-info.md + ${html_SOURCE_DIR}/irccdctl/command/rule-remove.md ${html_SOURCE_DIR}/irccdctl/command/server-cmode.md ${html_SOURCE_DIR}/irccdctl/command/server-cnotice.md ${html_SOURCE_DIR}/irccdctl/command/server-connect.md
--- a/doc/html/irccdctl/command/index.md Thu Jul 06 12:48:58 2017 +0200 +++ b/doc/html/irccdctl/command/index.md Fri Jul 07 12:22:17 2017 +0200 @@ -14,6 +14,7 @@ - [plugin-unload](plugin-unload.html) - [rule-list](rule-list.html) - [rule-info](rule-info.html) + - [rule-remove](rule-remove.html) - [server-cmode](server-cmode.html) - [server-cnotice](server-cnotice.html) - [server-connect](server-connect.html)
--- a/irccd/main.cpp Thu Jul 06 12:48:58 2017 +0200 +++ b/irccd/main.cpp Fri Jul 07 12:22:17 2017 +0200 @@ -322,6 +322,7 @@ instance->commands().add(std::make_unique<command::ServerTopicCommand>()); instance->commands().add(std::make_unique<command::RuleInfoCommand>()); instance->commands().add(std::make_unique<command::RuleListCommand>()); + instance->commands().add(std::make_unique<command::RuleRemoveCommand>()); // Load Javascript API and plugin loader. #if defined(WITH_JS)
--- a/irccdctl/cli.cpp Thu Jul 06 12:48:58 2017 +0200 +++ b/irccdctl/cli.cpp Fri Jul 07 12:22:17 2017 +0200 @@ -946,6 +946,43 @@ } /* + * RuleRemoveCli. + * ------------------------------------------------------------------ + */ + +RuleRemoveCli::RuleRemoveCli() + : Cli("rule-remove", + "remove a rule", + "rule-remove index", + "Remove an existing rule.\n\n" + "Example:\n" + "\tirccdctl rule-remove 0\n" + "\tirccdctl rule-remove 1") +{ +} + +void RuleRemoveCli::exec(Irccdctl &irccdctl, const std::vector<std::string> &args) +{ + if (args.size() < 1) + throw std::invalid_argument("rule-remove requires 1 argument"); + + int index = 0; + + try { + index = std::stoi(args[0]); + } catch (...) { + throw std::invalid_argument("invalid number '" + args[0] + "'"); + } + + auto result = request(irccdctl, { + { "command", "rule-remove" }, + { "index", index } + }); + + check(result); +} + +/* * WatchCli. * ------------------------------------------------------------------ */
--- a/irccdctl/cli.hpp Thu Jul 06 12:48:58 2017 +0200 +++ b/irccdctl/cli.hpp Fri Jul 07 12:22:17 2017 +0200 @@ -628,6 +628,28 @@ }; /* + * RuleRemoveCli + * ------------------------------------------------------------------ + */ + +/** + * \brief Implementation of irccdctl rule-remove. + */ +class RuleRemoveCli : public Cli { +public: + /** + * Default constructor. + */ + RuleRemoveCli(); + + /** + * \copydoc Cli::exec + */ + void exec(Irccdctl &client, const std::vector<std::string> &args) override; +}; + + +/* * WatchCli. * ------------------------------------------------------------------ */
--- a/irccdctl/main.cpp Thu Jul 06 12:48:58 2017 +0200 +++ b/irccdctl/main.cpp Fri Jul 07 12:22:17 2017 +0200 @@ -524,6 +524,7 @@ commands.push_back(std::make_unique<cli::ServerTopicCli>()); commands.push_back(std::make_unique<cli::RuleListCli>()); commands.push_back(std::make_unique<cli::RuleInfoCli>()); + commands.push_back(std::make_unique<cli::RuleRemoveCli>()); commands.push_back(std::make_unique<cli::WatchCli>()); }
--- a/libirccd/irccd/command.cpp Thu Jul 06 12:48:58 2017 +0200 +++ b/libirccd/irccd/command.cpp Fri Jul 07 12:22:17 2017 +0200 @@ -474,6 +474,25 @@ client.success("rule-info", toJson(irccd.rules().require(util::json::requireUint(args, "index")))); } +RuleRemoveCommand::RuleRemoveCommand() + : Command("rule-remove") +{ +} + +void RuleRemoveCommand::exec(Irccd &irccd, TransportClient &client, const nlohmann::json &args) +{ + unsigned position = util::json::requireUint(args, "index"); + + if (irccd.rules().length() == 0) + client.error("rule-remove", "rule list is empty"); + if (position >= irccd.rules().length()) + client.error("rule-remove", "index is out of range"); + else { + irccd.rules().remove(position); + client.success("rule-remove"); + } +} + } // !command } // !irccd
--- a/libirccd/irccd/command.hpp Thu Jul 06 12:48:58 2017 +0200 +++ b/libirccd/irccd/command.hpp Fri Jul 07 12:22:17 2017 +0200 @@ -490,6 +490,22 @@ void exec(Irccd &irccd, TransportClient &client, const nlohmann::json &args) override; }; +/** + * \brief Implementation of rule-remove transport command. + */ +class IRCCD_EXPORT RuleRemoveCommand : public Command { +public: + /** + * Constructor. + */ + RuleRemoveCommand(); + + /** + * \copydoc Command::exec + */ + void exec(Irccd &irccd, TransportClient &client, const nlohmann::json &args) override; +}; + } // !command } // !irccd
--- a/tests/CMakeLists.txt Thu Jul 06 12:48:58 2017 +0200 +++ b/tests/CMakeLists.txt Fri Jul 07 12:22:17 2017 +0200 @@ -28,6 +28,7 @@ add_subdirectory(cmd-plugin-unload) add_subdirectory(cmd-rule-list) add_subdirectory(cmd-rule-info) + add_subdirectory(cmd-rule-remove) add_subdirectory(cmd-server-cmode) add_subdirectory(cmd-server-cnotice) add_subdirectory(cmd-server-connect)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/cmd-rule-remove/CMakeLists.txt Fri Jul 07 12:22:17 2017 +0200 @@ -0,0 +1,23 @@ +# +# CMakeLists.txt -- CMake build system for irccd +# +# Copyright (c) 2013-2017 David Demelier <markand@malikania.fr> +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# + +irccd_define_test( + NAME cmd-rule-remove + SOURCES main.cpp + LIBRARIES libirccd libirccdctl +)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/cmd-rule-remove/main.cpp Fri Jul 07 12:22:17 2017 +0200 @@ -0,0 +1,160 @@ +/* + * main.cpp -- test rule-remove remote command + * + * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <command.hpp> +#include <command-tester.hpp> +#include <service.hpp> + +using namespace irccd; +using namespace irccd::command; + +class RuleRemoveCommandTest : public CommandTester { +protected: + nlohmann::json m_result; + + /* + * Rule sets are unordered so use this function to search a string in + * the JSON array. + */ + inline bool contains(const nlohmann::json &array, const std::string &str) + { + for (const auto &v : array) + if (v.is_string() && v == str) + return true; + + return false; + } + +public: + RuleRemoveCommandTest() + : CommandTester(std::make_unique<RuleRemoveCommand>()) + { + m_irccd.commands().add(std::make_unique<RuleListCommand>()); + m_irccd.rules().add(Rule( + { "s1", "s2" }, + { "c1", "c2" }, + { "o1", "o2" }, + { "p1", "p2" }, + { "onMessage", "onCommand" }, + RuleAction::Drop + )); + m_irccd.rules().add(Rule( + { "s1", }, + { "c1", }, + { "o1", }, + { "p1", }, + { "onMessage", }, + RuleAction::Accept + )); + m_irccdctl.client().onMessage.connect([&] (auto result) { + m_result = result; + }); + } +}; + +TEST_F(RuleRemoveCommandTest, basic) +{ + try { + m_irccdctl.client().request({ + { "command", "rule-remove" }, + { "index", 1 } + }); + + poll([&] () { + return m_result.is_object(); + }); + + ASSERT_TRUE(m_result.is_object()); + ASSERT_TRUE(m_result["status"].get<bool>()); + + m_result = nullptr; + m_irccdctl.client().request({{ "command", "rule-list" }}); + + poll([&] () { + return m_result.is_object(); + }); + + ASSERT_TRUE(m_result["list"].is_array()); + ASSERT_EQ(1U, m_result["list"].size()); + + auto servers = m_result["list"][0]["servers"]; + auto channels = m_result["list"][0]["channels"]; + auto plugins = m_result["list"][0]["plugins"]; + auto events = m_result["list"][0]["events"]; + + ASSERT_TRUE(contains(servers, "s1")); + ASSERT_TRUE(contains(servers, "s2")); + ASSERT_TRUE(contains(channels, "c1")); + ASSERT_TRUE(contains(channels, "c2")); + ASSERT_TRUE(contains(plugins, "p1")); + ASSERT_TRUE(contains(plugins, "p2")); + ASSERT_TRUE(contains(events, "onMessage")); + ASSERT_TRUE(contains(events, "onCommand")); + ASSERT_EQ("drop", m_result["list"][0]["action"]); + } catch (const std::exception &ex) { + FAIL() << ex.what(); + } +} + +TEST_F(RuleRemoveCommandTest, empty) +{ + m_irccd.rules().remove(0); + m_irccd.rules().remove(0); + + try { + m_irccdctl.client().request({ + { "command", "rule-remove" }, + { "index", 1 } + }); + + poll([&] () { + return m_result.is_object(); + }); + + ASSERT_TRUE(m_result.is_object()); + ASSERT_FALSE(m_result["status"].get<bool>()); + } catch (const std::exception &ex) { + FAIL() << ex.what(); + } +} + +TEST_F(RuleRemoveCommandTest, outOfBounds) +{ + try { + m_irccdctl.client().request({ + { "command", "rule-remove" }, + { "index", 123 } + }); + + poll([&] () { + return m_result.is_object(); + }); + + ASSERT_TRUE(m_result.is_object()); + ASSERT_FALSE(m_result["status"].get<bool>()); + } catch (const std::exception &ex) { + FAIL() << ex.what(); + } +} + +int main(int argc, char **argv) +{ + testing::InitGoogleTest(&argc, argv); + + return RUN_ALL_TESTS(); +}