Added tests for Iq Stanza errors
All checks were successful
PR Check / on-push-commit-check (push) Successful in 16m8s

This commit is contained in:
Ivan-lis 2024-12-19 17:47:38 +00:00
parent b322076552
commit 1ac4f0905c
3 changed files with 123 additions and 3 deletions

View file

@ -22,7 +22,7 @@ set(BOOST_INCLUDE_LIBRARIES "pfr;asio;serialization")
option(CPM_USE_LOCAL_PACKAGES "Use local packages" ON)
option(UTEMPL_USE_LOCAL_PACKAGE "Use utempl local package" OFF)
option(BUILD_EXECUTABLE ON)
option(LOG_LEVEL 0 "Available log levels: 0=TRACE, 1=DEBUG,2= INFO,3= WARN, 4=ERROR, 5=CRITICAL, 6=OFF") # Compile program with highest available log levle to trace everything
set(LOG_LEVEL 0 "Available log levels: 0=TRACE, 1=DEBUG,2= INFO,3= WARN, 4=ERROR, 5=CRITICAL, 6=OFF") # Compile program with highest available log levle to trace everything
set(UTEMPL_URL
"https://sha512sum.xyz/git/sha512sum/utempl"
CACHE STRING "utempl repository URL")
@ -272,7 +272,8 @@ if(ENABLE_EXAMPLES)
get_filename_component(EXAMPLE_NAME ${EXAMPLE_SRC} NAME_WE)
add_executable(${EXAMPLE_NAME} ${EXAMPLE_SRC})
target_link_libraries(${EXAMPLE_NAME} larra_xmpp)
target_compile_definitions(${EXAMPLE_NAME} PRIVATE SPDLOG_ACTIVE_LEVEL=${LOG_LEVEL})
# TODO(unknown): Fixed 'command line' error occured and uncomment below
# target_compile_definitions(${EXAMPLE_NAME} PRIVATE SPDLOG_ACTIVE_LEVEL=${LOG_LEVEL})
set_property(TARGET ${EXAMPLE_NAME} PROPERTY CXX_STANDARD 23)
set_target_properties(${EXAMPLE_NAME} PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/examples/output")

View file

@ -52,6 +52,15 @@ auto Coroutine() -> boost::asio::awaitable<void> {
auto main() -> int {
spdlog::set_level(spdlog::level::trace);
#ifdef SPDLOG_ACTIVE_LEVEL
std::println("\n\tCompiled max available log level: {}\n\tCurrently set log level: {}",
SPDLOG_ACTIVE_LEVEL,
std::to_underlying(spdlog::get_level()));
#else
std::println("\n\tCurrently set log level: {}", std::to_underlying(spdlog::get_level()));
#endif
boost::asio::io_context io_context;
boost::asio::co_spawn(io_context, Coroutine(), boost::asio::detached);
io_context.run();

View file

@ -1,10 +1,23 @@
#include <gtest/gtest.h>
#include <spdlog/spdlog.h>
#include <larra/iq.hpp>
#include <stdexcept>
namespace {
static constexpr auto kExpectedData = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<iq id=\"id\" type=\"get\"><some>37</some></iq>\n";
static constexpr auto kForbiddenErrorData = R"(<?xml version="1.0" encoding="UTF-8"?>
<iq id="42" to="name@server/res" type="error"><error type="auth"><forbidden xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/></error>
</iq>)";
static constexpr auto kExpectedSetData = R"(<?xml version="1.0" encoding="UTF-8"?>
<iq id="id" type="set"><some>37</some></iq>
)";
static constexpr auto kExpectedData = R"(<?xml version="1.0" encoding="UTF-8"?>
<iq id="id" type="get"><some>37</some></iq>
)";
struct SomeStruct {
int value;
constexpr auto operator==(const SomeStruct&) const -> bool = default;
@ -43,4 +56,101 @@ TEST(IQ, Parse) {
EXPECT_EQ(S::Parse(node), iq);
}
TEST(IQ, ParseForbiddenError) {
std::istringstream xml_stream(kForbiddenErrorData);
xmlpp::DomParser parser;
parser.parse_stream(xml_stream);
using S = Serialization<Iq<SomeStruct>>;
xmlpp::Document* doc = parser.get_document();
auto iqRes = S::Parse(doc->get_root_node());
ASSERT_TRUE(std::holds_alternative<IqError>(iqRes));
auto errorRes = std::get<IqError>(iqRes);
ASSERT_TRUE(std::holds_alternative<iq::error::impl::Forbidden>(errorRes.payload));
}
TEST(IQ, IqErrThrowVisitorThrow) {
std::istringstream xml_stream(kForbiddenErrorData);
xmlpp::DomParser parser;
parser.parse_stream(xml_stream);
using S = Serialization<Iq<SomeStruct>>;
xmlpp::Document* doc = parser.get_document();
auto iqRes = S::Parse(doc->get_root_node());
ASSERT_TRUE(std::holds_alternative<IqError>(iqRes));
static constexpr auto visitorErrMsg = "Test Error";
static constexpr auto throwErrMsg = "Stanza IQ Error: Forbidden";
try {
std::visit(utempl::Overloaded([](iq::Result<SomeStruct> r) {}, IqErrThrowVisitor<SomeStruct>{visitorErrMsg}), std::move(iqRes));
} catch(const iq::error::impl::IqBaseError& err) {
ASSERT_STREQ(throwErrMsg, err.what());
return;
} catch(const std::runtime_error& err) {
ASSERT_TRUE(false) << "Invalid throw type throw";
} catch(...) {
ASSERT_TRUE(false) << "Unexpected throw";
}
ASSERT_TRUE(false) << "Expected throwing an exception due to an error in output";
}
TEST(IQ, IqErrThrowVisitorThrowGet) {
std::istringstream xml_stream(kExpectedData);
xmlpp::DomParser parser;
parser.parse_stream(xml_stream);
using S = Serialization<Iq<SomeStruct>>;
xmlpp::Document* doc = parser.get_document();
auto iqRes = S::Parse(doc->get_root_node());
ASSERT_TRUE(std::holds_alternative<iq::Get<SomeStruct>>(iqRes)) << "\tERROR: Unexpected parse result";
static constexpr auto visitorErrMsg = "Test Error";
static constexpr auto throwErrMsg = "Test Error: 'Get' is an invalid type for IQ result. Expected 'Result' or 'Error'";
try {
std::visit(utempl::Overloaded([](iq::Result<SomeStruct> r) {}, IqErrThrowVisitor<SomeStruct>{"Test Error"}), std::move(iqRes));
} catch(const iq::error::impl::IqBaseError& err) {
ASSERT_TRUE(false) << "\tERROR: Invalid throw type throw";
} catch(const std::runtime_error& err) {
ASSERT_STREQ(throwErrMsg, err.what());
return;
} catch(...) {
ASSERT_TRUE(false) << "\tERROR: Unexpected throw";
}
ASSERT_TRUE(false) << "\tERROR: Expected throwing an exception due to an error in output";
}
TEST(IQ, IqErrThrowVisitorThrowSet) {
std::istringstream xml_stream(kExpectedSetData);
xmlpp::DomParser parser;
parser.parse_stream(xml_stream);
using S = Serialization<Iq<SomeStruct>>;
xmlpp::Document* doc = parser.get_document();
auto iqRes = S::Parse(doc->get_root_node());
ASSERT_TRUE(std::holds_alternative<iq::Set<SomeStruct>>(iqRes)) << "\tERROR: Unexpected parse result";
static constexpr auto visitorErrMsg = "Test Error";
static constexpr auto throwErrMsg = "Test Error: 'Set' is an invalid type for IQ result. Expected 'Result' or 'Error'";
try {
std::visit(utempl::Overloaded([](iq::Result<SomeStruct> r) {}, IqErrThrowVisitor<SomeStruct>{"Test Error"}), std::move(iqRes));
} catch(const iq::error::impl::IqBaseError& err) {
ASSERT_TRUE(false) << "\tERROR: Invalid throw type throw";
} catch(const std::runtime_error& err) {
ASSERT_STREQ(throwErrMsg, err.what());
return;
} catch(...) {
ASSERT_TRUE(false) << "\tERROR: Unexpected throw";
}
ASSERT_TRUE(false) << "\tERROR: Expected throwing an exception due to an error in output";
}
} // namespace larra::xmpp