From 8e03ef23d87269ce97b3014e46fc47afd903db65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9D=D0=B8=D0=BA=D0=BE=D0=BB=D0=B0=D0=B9=20=D0=A1=D1=82?= =?UTF-8?q?=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2?= Date: Wed, 3 May 2023 16:53:27 +0300 Subject: [PATCH] Add tests for http server --- CMakeLists.txt | 6 +- server/CMakeLists.txt | 2 +- server/internal/CMakeLists.txt | 5 + server/internal/httpServer/CMakeLists.txt | 24 ++++ server/internal/httpServer/include/Header.h | 11 ++ .../httpServer/include/HttpConnection.h | 33 +++++ .../internal/httpServer/include/HttpServer.h | 30 +++++ server/internal/httpServer/include/Parser.h | 57 ++++++++ server/internal/httpServer/include/Request.h | 17 +++ server/internal/httpServer/include/Response.h | 38 ++++++ server/internal/httpServer/include/Router.h | 35 +++++ .../internal/httpServer/include/Serializer.h | 14 ++ .../httpServer/include/SolutionManager.h | 27 ++++ .../internal/httpServer/include/TaskManager.h | 25 ++++ .../internal/httpServer/include/UserManager.h | 25 ++++ .../httpServer/src/HttpConnection.cpp | 16 +++ server/internal/httpServer/src/HttpServer.cpp | 20 +++ server/internal/httpServer/src/Parser.cpp | 17 +++ server/internal/httpServer/src/Response.cpp | 5 + server/internal/httpServer/src/Router.cpp | 15 +++ .../httpServer/src/SolutionManager.cpp | 26 ++++ .../internal/httpServer/src/TaskManager.cpp | 24 ++++ .../internal/httpServer/src/UserManager.cpp | 24 ++++ .../internal/httpServer/tests/CMakeLists.txt | 16 +++ .../internal/httpServer/tests/RouterSuite.cpp | 124 ++++++++++++++++++ .../httpServer/tests/SolutionManagerSuite.cpp | 60 +++++++++ .../httpServer/tests/TaskManagerSuite.cpp | 42 ++++++ .../httpServer/tests/UserManagerSuite.cpp | 48 +++++++ server/internal/httpServer/tests/main.cpp | 8 ++ .../httpServer/virtual/ISolutionManager.h | 17 +++ .../httpServer/virtual/ITaskManager.h | 17 +++ .../httpServer/virtual/IUserManager.h | 17 +++ 32 files changed, 841 insertions(+), 4 deletions(-) create mode 100644 server/internal/httpServer/CMakeLists.txt create mode 100644 server/internal/httpServer/include/Header.h create mode 100644 server/internal/httpServer/include/HttpConnection.h create mode 100644 server/internal/httpServer/include/HttpServer.h create mode 100644 server/internal/httpServer/include/Parser.h create mode 100644 server/internal/httpServer/include/Request.h create mode 100644 server/internal/httpServer/include/Response.h create mode 100644 server/internal/httpServer/include/Router.h create mode 100644 server/internal/httpServer/include/Serializer.h create mode 100644 server/internal/httpServer/include/SolutionManager.h create mode 100644 server/internal/httpServer/include/TaskManager.h create mode 100644 server/internal/httpServer/include/UserManager.h create mode 100644 server/internal/httpServer/src/HttpConnection.cpp create mode 100644 server/internal/httpServer/src/HttpServer.cpp create mode 100644 server/internal/httpServer/src/Parser.cpp create mode 100644 server/internal/httpServer/src/Response.cpp create mode 100644 server/internal/httpServer/src/Router.cpp create mode 100644 server/internal/httpServer/src/SolutionManager.cpp create mode 100644 server/internal/httpServer/src/TaskManager.cpp create mode 100644 server/internal/httpServer/src/UserManager.cpp create mode 100644 server/internal/httpServer/tests/CMakeLists.txt create mode 100644 server/internal/httpServer/tests/RouterSuite.cpp create mode 100644 server/internal/httpServer/tests/SolutionManagerSuite.cpp create mode 100644 server/internal/httpServer/tests/TaskManagerSuite.cpp create mode 100644 server/internal/httpServer/tests/UserManagerSuite.cpp create mode 100644 server/internal/httpServer/tests/main.cpp create mode 100644 server/internal/httpServer/virtual/ISolutionManager.h create mode 100644 server/internal/httpServer/virtual/ITaskManager.h create mode 100644 server/internal/httpServer/virtual/IUserManager.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 41c84fa..451ba69 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,13 +13,13 @@ if(BUILD_DEV) enable_testing() message("Building dev version") # set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage -O0 -fprofile-arcs -ftest-coverage") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -Wall -Wextra -pedantic -Wformat=2 -Wfloat-equal -Wconversion \ - -Wlogical-op -Wshift-overflow=2 -Wduplicated-cond -Wcast-qual -Wcast-align -lpq -lpqxx") +# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -Wall -Wextra -pedantic -Wformat=2 -Wfloat-equal -Wconversion \ +# -Wlogical-op -Wshift-overflow=2 -Wduplicated-cond -Wcast-qual -Wcast-align -lpq -lpqxx") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -coverage -lgcov") if(SANITIZE_BUILD) message("Sanitizers ON") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address,undefined -fno-sanitize-recover=all -fsanitize-undefined-trap-on-error") +# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address,undefined -fno-sanitize-recover=all -fsanitize-undefined-trap-on-error") endif(SANITIZE_BUILD) endif(BUILD_DEV) diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt index 2e5c3dc..86cd702 100644 --- a/server/CMakeLists.txt +++ b/server/CMakeLists.txt @@ -3,7 +3,7 @@ project(SourcedOut CXX) # find_package(antlr4-runtime REQUIRED) find_package(Boost 1.8.1 REQUIRED) # find_package(libpqxx REQUIRED) -find_library(PQXX_LIB pqxx) +#find_library(PQXX_LIB pqxx) find_package(GTest REQUIRED) find_package(nlohmann_json REQUIRED) message(STATUS ${nlohmann_json_LIBRARIES}) diff --git a/server/internal/CMakeLists.txt b/server/internal/CMakeLists.txt index f23cb6b..a6a49c7 100644 --- a/server/internal/CMakeLists.txt +++ b/server/internal/CMakeLists.txt @@ -3,6 +3,7 @@ add_subdirectory(entities) add_subdirectory(dbManager) add_subdirectory(repository) add_subdirectory(service) +add_subdirectory(httpServer) set(libEntities_LIB ${libEntities_LIB} PARENT_SCOPE) set(libEntities_INCLUDE_DIRS ${libEntities_INCLUDE_DIRS} PARENT_SCOPE) @@ -16,4 +17,8 @@ set(SERVICE_INCLUDE_DIRS ${SERVICE_lib_INCLUDE_DIRS} PARENT_SCOPE) set(libDbManager_LIB ${libDbManager_LIB} PARENT_SCOPE) set(libDbManager_INCLUDE_DIRS ${libDbManager_INCLUDE_DIRS} PARENT_SCOPE) +set(HTTPSERVER_lib_LIB ${HTTPSERVER_lib_LIB} PARENT_SCOPE) +set(HTTPSERVER_lib_INCLUDE_DIRS ${HTTPSERVER_lib_INCLUDE_DIRS} PARENT_SCOPE) + message("DbManager = ${libDbManager_LIB}") +message("HTTPSERVER = " ${HTTPSERVER_lib_LIB}) diff --git a/server/internal/httpServer/CMakeLists.txt b/server/internal/httpServer/CMakeLists.txt new file mode 100644 index 0000000..871e221 --- /dev/null +++ b/server/internal/httpServer/CMakeLists.txt @@ -0,0 +1,24 @@ +project("HttpServerLib") + +set(CMAKE_CXX_STANDARD 20) + +file(GLOB SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp) +file(GLOB INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR}/virtual) +file(GLOB INCLUDES ${CMAKE_CURRENT_SOURCE_DIR}/include/*.h ${CMAKE_CURRENT_SOURCE_DIR}/virtual/*.h) + +include_directories(${INCLUDE_DIRS} ${Boost_INCLUDE_DIR} ${libEntities_INCLUDE_DIRS} ${SERVICE_lib_INCLUDE_DIRS}) +add_library(${PROJECT_NAME} ${SOURCES} ${INCLUDES}) + +message("SERVICE_lib_LIB = ${SERVICE_lib_LIB}") +message("SERVICE_lib_INCLUDE_DIRS = ${SERVICE_lib_INCLUDE_DIRS}") + +target_link_libraries(${PROJECT_NAME} ${SERVICE_lib_LIB} ${libEntities_LIB} ${Boost_LIBRARIES}) + +set(HTTPSERVER_lib_LIB ${PROJECT_NAME}) +set(HTTPSERVER_lib_LIB ${HTTPSERVER_lib_LIB} PARENT_SCOPE) + +set(HTTPSERVER_lib_INCLUDE_DIRS ${INCLUDE_DIRS}) +set(HTTPSERVER_lib_INCLUDE_DIRS ${HTTPSERVER_lib_INCLUDE_DIRS} PARENT_SCOPE) + +enable_testing() +add_subdirectory(tests) \ No newline at end of file diff --git a/server/internal/httpServer/include/Header.h b/server/internal/httpServer/include/Header.h new file mode 100644 index 0000000..a3e50dd --- /dev/null +++ b/server/internal/httpServer/include/Header.h @@ -0,0 +1,11 @@ +#ifndef APP_HTTPSERVER_HTTPSERVER_HEADER_H_ +#define APP_HTTPSERVER_HTTPSERVER_HEADER_H_ + +#include + +struct Header { + std::string name; + std::string value; +}; + +#endif // APP_HTTPSERVER_HTTPSERVER_HEADER_H_ diff --git a/server/internal/httpServer/include/HttpConnection.h b/server/internal/httpServer/include/HttpConnection.h new file mode 100644 index 0000000..cee5f56 --- /dev/null +++ b/server/internal/httpServer/include/HttpConnection.h @@ -0,0 +1,33 @@ +#ifndef APP_HTTPSERVER_HTTPSERVER_HTTPCONNECTION_H_ +#define APP_HTTPSERVER_HTTPSERVER_HTTPCONNECTION_H_ + + +#include +#include + +#include "Response.h" +#include "Request.h" +#include "Router.h" +#include "Parser.h" + +class HttpConnection : public std::enable_shared_from_this, + private boost::noncopyable { + public: + explicit HttpConnection(boost::asio::io_service& io_service); + boost::asio::ip::tcp::socket& getSocket(); + void start(); + protected: + void handleRead(const boost::system::error_code& e, + std::size_t bytes_transferred); + void handleWrite(const boost::system::error_code& e); + + boost::asio::io_service::strand strand; + boost::asio::ip::tcp::socket socket; + std::shared_ptr router; + std::array buffer{}; + Request request; + Parser parser; + Response response; +}; + +#endif // APP_HTTPSERVER_HTTPSERVER_HTTPCONNECTION_H_ diff --git a/server/internal/httpServer/include/HttpServer.h b/server/internal/httpServer/include/HttpServer.h new file mode 100644 index 0000000..083d224 --- /dev/null +++ b/server/internal/httpServer/include/HttpServer.h @@ -0,0 +1,30 @@ +#ifndef APP_HTTPSERVER_HTTPSERVER_HTTPSERVER_H_ +#define APP_HTTPSERVER_HTTPSERVER_HTTPSERVER_H_ + +#include +#include +#include +#include +#include + +#include "HttpConnection.h" +#include "Router.h" + +class HttpServer : private boost::noncopyable { + public: + HttpServer(const std::string& address, const std::string& port, std::size_t thread_pool_size); + void run(); + private: + void startAccept(); + void handleAccept(const boost::system::error_code& e); + void handleStop(); + + std::size_t thread_pool_size; + boost::asio::io_service io_service; + boost::asio::signal_set signals; + boost::asio::ip::tcp::acceptor acceptor; + std::shared_ptr connection; +}; + + +#endif // APP_HTTPSERVER_HTTPSERVER_HTTPSERVER_H_ diff --git a/server/internal/httpServer/include/Parser.h b/server/internal/httpServer/include/Parser.h new file mode 100644 index 0000000..142f234 --- /dev/null +++ b/server/internal/httpServer/include/Parser.h @@ -0,0 +1,57 @@ +#ifndef APP_HTTPSERVER_HTTPSERVER_PARSER_H_ +#define APP_HTTPSERVER_HTTPSERVER_PARSER_H_ + +#include "Request.h" + +#include +#include + +class Parser { + public: + Parser(); + void reset(); + + template + boost::tuple parse(Request& req, + InputIterator begin, InputIterator end) { + while (begin != end) { + boost::tribool result = consume(req, *begin++); + if (result || !result) + return boost::make_tuple(result, begin); + } + boost::tribool result = boost::indeterminate; + return boost::make_tuple(result, begin); + } + + private: + boost::tribool consume(Request& req, char input); + static bool isChar(int c); + static bool isCtl(int c); + static bool isTspecial(int c); + static bool isDigit(int c); + + enum state { + method_start, + method, + uri, + http_version_h, + http_version_t_1, + http_version_t_2, + http_version_p, + http_version_slash, + http_version_major_start, + http_version_major, + http_version_minor_start, + http_version_minor, + expecting_newline_1, + header_line_start, + header_lws, + header_name, + space_before_header_value, + header_value, + expecting_newline_2, + expecting_newline_3 + } state; +}; + +#endif // APP_HTTPSERVER_HTTPSERVER_PARSER_H_ diff --git a/server/internal/httpServer/include/Request.h b/server/internal/httpServer/include/Request.h new file mode 100644 index 0000000..386f9b3 --- /dev/null +++ b/server/internal/httpServer/include/Request.h @@ -0,0 +1,17 @@ +#ifndef APP_HTTPSERVER_HTTPSERVER_REQUEST_H_ +#define APP_HTTPSERVER_HTTPSERVER_REQUEST_H_ + +#include +#include + +#include "Header.h" + +struct Request { + std::string method; + std::string uri; + int http_version_major; + int http_version_minor; + std::vector
headers; +}; + +#endif // APP_HTTPSERVER_HTTPSERVER_REQUEST_H_ diff --git a/server/internal/httpServer/include/Response.h b/server/internal/httpServer/include/Response.h new file mode 100644 index 0000000..6dd3a1d --- /dev/null +++ b/server/internal/httpServer/include/Response.h @@ -0,0 +1,38 @@ +#ifndef APP_HTTPSERVER_HTTPSERVER_REPLY_H_ +#define APP_HTTPSERVER_HTTPSERVER_REPLY_H_ + +#include +#include +#include + +#include "Header.h" + +struct Response { + enum status_type { + ok = 200, + created = 201, + accepted = 202, + no_content = 204, + multiple_choices = 300, + moved_permanently = 301, + moved_temporarily = 302, + not_modified = 304, + bad_request = 400, + unauthorized = 401, + forbidden = 403, + not_found = 404, + internal_server_error = 500, + not_implemented = 501, + bad_gateway = 502, + service_unavailable = 503 + } status; + + std::vector
headers; + std::string content; + + std::vector toBuffers(); + static Response stockResponse(status_type status); +}; + + +#endif // APP_HTTPSERVER_HTTPSERVER_REPLY_H_ diff --git a/server/internal/httpServer/include/Router.h b/server/internal/httpServer/include/Router.h new file mode 100644 index 0000000..50267ea --- /dev/null +++ b/server/internal/httpServer/include/Router.h @@ -0,0 +1,35 @@ +#ifndef APP_HTTPSERVER_HTTPSERVER_ROUTER_H_ +#define APP_HTTPSERVER_HTTPSERVER_ROUTER_H_ + +#include +#include +#include + +#include "SolutionManager.h" +#include "UserManager.h" +#include "TaskManager.h" +#include "Response.h" +#include "Request.h" + +class Router : private boost::noncopyable { + public: + Router(); + void handleRequest(const Request& req, Response& res); + void setSolutionManager(std::shared_ptr mng) { + solutionManager = mng; + } + void setUserManager(std::shared_ptr mng) { + userManager = mng; + } + void setTaskManager(std::shared_ptr mng) { + taskManager = mng; + } + private: + std::shared_ptr solutionManager; + std::shared_ptr userManager; + std::shared_ptr taskManager; + static bool decodeUrl(const std::string& in, std::string& out); +}; + + +#endif // APP_HTTPSERVER_HTTPSERVER_ROUTER_H_ diff --git a/server/internal/httpServer/include/Serializer.h b/server/internal/httpServer/include/Serializer.h new file mode 100644 index 0000000..a8a68be --- /dev/null +++ b/server/internal/httpServer/include/Serializer.h @@ -0,0 +1,14 @@ +#ifndef APP_HTTPSERVER_HTTPSERVER_MANAGERS_SERIALIZER_H_ +#define APP_HTTPSERVER_HTTPSERVER_MANAGERS_SERIALIZER_H_ + +#include +#include +#include + +#include "Solution.hpp" +#include "User.hpp" + +class Serializer {}; + + +#endif // APP_HTTPSERVER_HTTPSERVER_MANAGERS_SERIALIZER_H_ diff --git a/server/internal/httpServer/include/SolutionManager.h b/server/internal/httpServer/include/SolutionManager.h new file mode 100644 index 0000000..5a11065 --- /dev/null +++ b/server/internal/httpServer/include/SolutionManager.h @@ -0,0 +1,27 @@ +#ifndef APP_HTTPSERVER_HTTPSERVER_MANAGERS_SolutionMANAGER_H_ +#define APP_HTTPSERVER_HTTPSERVER_MANAGERS_SolutionMANAGER_H_ + +#include +#include + +#include "Response.h" +#include "Request.h" +#include "Serializer.h" +#include "ISolutionManager.h" +#include "ISolutionService.h" + +class SolutionManager : public ISolutionManager { + public: + SolutionManager(); + Response getAllSolutions(const Request &req) override; + Response createSolution(const Request &req) override; + Response getMetrics(const Request &req) override; + void setService(std::shared_ptr service); + + private: + std::shared_ptr solutionService; + std::shared_ptr serializer; + static std::string getParam(const std::string& path, const std::string& name); +}; + +#endif // APP_HTTPSERVER_HTTPSERVER_MANAGERS_SolutionMANAGER_H_ diff --git a/server/internal/httpServer/include/TaskManager.h b/server/internal/httpServer/include/TaskManager.h new file mode 100644 index 0000000..c49b08b --- /dev/null +++ b/server/internal/httpServer/include/TaskManager.h @@ -0,0 +1,25 @@ +#ifndef APP_HTTPSERVER_HTTPSERVER_MANAGERS_TaskMANAGER_H_ +#define APP_HTTPSERVER_HTTPSERVER_MANAGERS_TaskMANAGER_H_ + +#include +#include + +#include "Response.h" +#include "Request.h" +#include "Serializer.h" +#include "ITaskManager.h" +#include "ITaskService.h" + +class TaskManager : public ITaskManager { +public: + TaskManager(); + Response createTask(const Request &req) override; + Response getAllTasks(const Request &req) override; + void setService(std::shared_ptr service); +private: + std::shared_ptr taskService; + std::shared_ptr serializer; + static std::string getParam(const std::string& path, const std::string& name); +}; + +#endif // APP_HTTPSERVER_HTTPSERVER_MANAGERS_TaskMANAGER_H_ diff --git a/server/internal/httpServer/include/UserManager.h b/server/internal/httpServer/include/UserManager.h new file mode 100644 index 0000000..9043ada --- /dev/null +++ b/server/internal/httpServer/include/UserManager.h @@ -0,0 +1,25 @@ +#ifndef APP_HTTPSERVER_HTTPSERVER_MANAGERS_USERMANAGER_H_ +#define APP_HTTPSERVER_HTTPSERVER_MANAGERS_USERMANAGER_H_ + +#include +#include + +#include "Response.h" +#include "Request.h" +#include "Serializer.h" +#include "IUserManager.h" +#include "IUserService.h" + +class UserManager : public IUserManager { + public: + UserManager(); + Response loginUser(const Request &req) override; + Response registerUser(const Request &req) override; + void setService(std::shared_ptr service); + private: + std::shared_ptr userService; + std::shared_ptr serializer; + static std::string getParam(const std::string& path, const std::string& name); +}; + +#endif // APP_HTTPSERVER_HTTPSERVER_MANAGERS_USERMANAGER_H_ diff --git a/server/internal/httpServer/src/HttpConnection.cpp b/server/internal/httpServer/src/HttpConnection.cpp new file mode 100644 index 0000000..412f670 --- /dev/null +++ b/server/internal/httpServer/src/HttpConnection.cpp @@ -0,0 +1,16 @@ +#include "HttpConnection.h" + +#include + +HttpConnection::HttpConnection(boost::asio::io_service& io_service) + : strand(io_service), + socket(io_service) {} + +boost::asio::ip::tcp::socket& HttpConnection::getSocket() {} + +void HttpConnection::start() {} + +void HttpConnection::handleRead(const boost::system::error_code& e, + std::size_t bytes_transferred) {} + +void HttpConnection::handleWrite(const boost::system::error_code& e) {} diff --git a/server/internal/httpServer/src/HttpServer.cpp b/server/internal/httpServer/src/HttpServer.cpp new file mode 100644 index 0000000..246b4f0 --- /dev/null +++ b/server/internal/httpServer/src/HttpServer.cpp @@ -0,0 +1,20 @@ +#include "HttpServer.h" + +#include +#include +#include +#include + +HttpServer::HttpServer(const std::string& address, const std::string& port, std::size_t thread_pool_size) + : thread_pool_size(thread_pool_size), + signals(io_service), + acceptor(io_service), + connection() {} + +void HttpServer::run() {} + +void HttpServer::startAccept() {} + +void HttpServer::handleAccept(const boost::system::error_code& e) {} + +void HttpServer::handleStop() {} diff --git a/server/internal/httpServer/src/Parser.cpp b/server/internal/httpServer/src/Parser.cpp new file mode 100644 index 0000000..86b9541 --- /dev/null +++ b/server/internal/httpServer/src/Parser.cpp @@ -0,0 +1,17 @@ +#include "Parser.h" +#include "Request.h" + +Parser::Parser() + : state(method_start) {} + +void Parser::reset() {} + +boost::tribool Parser::consume(Request& req, char input) {} + +bool Parser::isChar(int c) {} + +bool Parser::isCtl(int c) {} + +bool Parser::isTspecial(int c) {} + +bool Parser::isDigit(int c) {} diff --git a/server/internal/httpServer/src/Response.cpp b/server/internal/httpServer/src/Response.cpp new file mode 100644 index 0000000..f688c34 --- /dev/null +++ b/server/internal/httpServer/src/Response.cpp @@ -0,0 +1,5 @@ +#include "Response.h" + +std::vector Response::toBuffers() {} + +Response Response::stockResponse(Response::status_type status) {} diff --git a/server/internal/httpServer/src/Router.cpp b/server/internal/httpServer/src/Router.cpp new file mode 100644 index 0000000..e235dee --- /dev/null +++ b/server/internal/httpServer/src/Router.cpp @@ -0,0 +1,15 @@ +#include "Router.h" + +#include +#include +#include + +#include "Response.h" + +Router::Router() : + solutionManager(std::make_shared()), + userManager(std::make_shared()) {} + +void Router::handleRequest(const Request& req, Response& res) {} + +bool Router::decodeUrl(const std::string& in, std::string& out) {} diff --git a/server/internal/httpServer/src/SolutionManager.cpp b/server/internal/httpServer/src/SolutionManager.cpp new file mode 100644 index 0000000..3a93e41 --- /dev/null +++ b/server/internal/httpServer/src/SolutionManager.cpp @@ -0,0 +1,26 @@ +// +// Created by Николай Степанов on 03.05.2023. +// +#include "SolutionManager.h" + +SolutionManager::SolutionManager() {} + +Response SolutionManager::getAllSolutions(const Request &req) { + return Response(); +} + +Response SolutionManager::createSolution(const Request &req) { + return Response(); +} + +Response SolutionManager::getMetrics(const Request &req) { + return Response(); +} + +std::string SolutionManager::getParam(const std::string &path, const std::string &name) { + return std::string(); +} + +void SolutionManager::setService(std::shared_ptr service) { + solutionService = service; +} diff --git a/server/internal/httpServer/src/TaskManager.cpp b/server/internal/httpServer/src/TaskManager.cpp new file mode 100644 index 0000000..ca3875d --- /dev/null +++ b/server/internal/httpServer/src/TaskManager.cpp @@ -0,0 +1,24 @@ +// +// Created by Николай Степанов on 03.05.2023. +// +#include "TaskManager.h" + +TaskManager::TaskManager() { + +} + +Response TaskManager::createTask(const Request &req) { + return Response(); +} + +Response TaskManager::getAllTasks(const Request &req) { + return Response(); +} + +std::string TaskManager::getParam(const std::string &path, const std::string &name) { + return std::string(); +} + +void TaskManager::setService(std::shared_ptr service) { + taskService = service; +} diff --git a/server/internal/httpServer/src/UserManager.cpp b/server/internal/httpServer/src/UserManager.cpp new file mode 100644 index 0000000..4137716 --- /dev/null +++ b/server/internal/httpServer/src/UserManager.cpp @@ -0,0 +1,24 @@ +// +// Created by Николай Степанов on 03.05.2023. +// +#include "UserManager.h" + +UserManager::UserManager() { + +} + +Response UserManager::loginUser(const Request &req) { + return Response(); +} + +Response UserManager::registerUser(const Request &req) { + return Response(); +} + +std::string UserManager::getParam(const std::string &path, const std::string &name) { + return std::string(); +} + +void UserManager::setService(std::shared_ptr service) { + userService = service; +} diff --git a/server/internal/httpServer/tests/CMakeLists.txt b/server/internal/httpServer/tests/CMakeLists.txt new file mode 100644 index 0000000..c635b60 --- /dev/null +++ b/server/internal/httpServer/tests/CMakeLists.txt @@ -0,0 +1,16 @@ +project(test_httpserver) + +set(CMAKE_CXX_STANDARD 20) +add_compile_options(-coverage) + +file(GLOB SOURCES *.cpp) + +enable_testing() +find_package(GTest REQUIRED) + +add_executable(${PROJECT_NAME} ${SOURCES}) + +target_link_libraries(${PROJECT_NAME} ${HTTPSERVER_lib_LIB} GTest::GTest GTest::gmock) +target_include_directories(${PROJECT_NAME} PUBLIC ${HTTPSERVER_lib_INCLUDE_DIRS} ${SERVICE_lib_INCLUDE_DIRS}) + +add_test(test_httpserver test_httpserver) \ No newline at end of file diff --git a/server/internal/httpServer/tests/RouterSuite.cpp b/server/internal/httpServer/tests/RouterSuite.cpp new file mode 100644 index 0000000..6fd7331 --- /dev/null +++ b/server/internal/httpServer/tests/RouterSuite.cpp @@ -0,0 +1,124 @@ +#include +#include + +#include "Router.h" +#include "ISolutionManager.h" +#include "ITaskManager.h" +#include "IUserManager.h" + +class SolutionManagerMock : public ISolutionManager { +public: + SolutionManagerMock() = default; + MOCK_METHOD(Response, getAllSolutions, (const Request &req), (override)); + MOCK_METHOD(Response, createSolution, (const Request& req), (override)); + MOCK_METHOD(Response, getMetrics, (const Request& req), (override)); +}; + +class TaskManagerMock : public ITaskManager { +public: + TaskManagerMock() = default; + MOCK_METHOD(Response, createTask, (const Request &req), (override)); + MOCK_METHOD(Response, getAllTasks, (const Request& req), (override)); +}; + +class UserManagerMock : public IUserManager { +public: + UserManagerMock() = default; + MOCK_METHOD(Response, loginUser, (const Request &req), (override)); + MOCK_METHOD(Response, registerUser, (const Request& req), (override)); +}; + +class RouterSuite : public ::testing::Test { +protected: + void SetUp() override { + router.setSolutionManager(solutionManager); + router.setUserManager(userManager); + router.setTaskManager(taskManager); + } + + std::shared_ptr userManager = std::make_shared(); + std::shared_ptr taskManager = std::make_shared(); + std::shared_ptr solutionManager = std::make_shared(); + Router router; +}; + +TEST_F(RouterSuite, RegisterUserTest) { + Request req; + req.method = "POST"; + req.uri = "/user/register"; + Response res; + EXPECT_CALL(*userManager, registerUser); + router.handleRequest(req, res); +} + +TEST_F(RouterSuite, LoginUserTest) { + Request req; + req.method = "GET"; + req.uri = "/user/login"; + Response res; + EXPECT_CALL(*userManager, loginUser); + router.handleRequest(req, res); +} + +TEST_F(RouterSuite, GetAllTasksTest) { + Request req; + req.method = "GET"; + req.uri = "/task/all"; + Response res; + EXPECT_CALL(*taskManager, getAllTasks); + router.handleRequest(req, res); +} + +TEST_F(RouterSuite, CreateTaskTest) { + Request req; + req.method = "POST"; + req.uri = "/task/create"; + Response res; + EXPECT_CALL(*taskManager, createTask); + router.handleRequest(req, res); +} + +TEST_F(RouterSuite, GetSolutionMetricsTest) { + Request req; + req.method = "GET"; + req.uri = "/solution/metrics"; + Response res; + EXPECT_CALL(*solutionManager, getMetrics); + router.handleRequest(req, res); +} + +TEST_F(RouterSuite, CreateSolutionTest) { + Request req; + req.method = "POST"; + req.uri = "/solution/create"; + Response res; + EXPECT_CALL(*solutionManager, createSolution); + router.handleRequest(req, res); +} + +TEST_F(RouterSuite, GetAllSolutionsTest) { + Request req; + req.method = "GET"; + req.uri = "/solution/all"; + Response res; + EXPECT_CALL(*solutionManager, getAllSolutions); + router.handleRequest(req, res); +} + +TEST_F(RouterSuite, BadMethodTest) { + Request req; + req.method = ""; + req.uri = "/solution/all"; + Response res; + router.handleRequest(req, res); + EXPECT_EQ(res.status, 500); +} + +TEST_F(RouterSuite, BadUriTest) { + Request req; + req.method = "GET"; + req.uri = ""; + Response res; + router.handleRequest(req, res); + EXPECT_EQ(res.status, 500); +} \ No newline at end of file diff --git a/server/internal/httpServer/tests/SolutionManagerSuite.cpp b/server/internal/httpServer/tests/SolutionManagerSuite.cpp new file mode 100644 index 0000000..fb5cc54 --- /dev/null +++ b/server/internal/httpServer/tests/SolutionManagerSuite.cpp @@ -0,0 +1,60 @@ +#include +#include + +#include "SolutionManager.h" +#include "ISolutionService.h" + +class SolutionServiceMock : public ISolutionService { +public: + SolutionServiceMock() = default; + MOCK_METHOD(Solution, createSolution, (size_t userId, size_t taskId, std::string source), (override)); + MOCK_METHOD(std::vector, getSolutionsByUserAndTaskId, (size_t userId, size_t taskId), (override)); + MOCK_METHOD((std::pair), getMetrics, (size_t solId), (override)); + MOCK_METHOD(void, deleteSolutionById, (size_t solId), (override)); +}; + +class SolutionManagerSuite : public ::testing::Test { +protected: + void SetUp() override { + manager.setService(solutionService); + } + + std::shared_ptr solutionService = std::make_shared(); + SolutionManager manager; +}; + +TEST_F(SolutionManagerSuite, GetSolutionByUserAndTaskTest) { + Request req; + Header h1, h2; + h1.name = "user_id"; + h2.name = "task_id"; + h1.value = '1'; + h2.value = '2'; + req.headers = {h1, h2}; + EXPECT_CALL(*solutionService, getSolutionsByUserAndTaskId(1, 2)); + manager.getAllSolutions(req); +} + +TEST_F(SolutionManagerSuite, GetMetricsTest) { + Request req; + Header h1; + h1.name = "sol_id"; + h1.value = "1"; + req.headers = {h1}; + EXPECT_CALL(*solutionService, getMetrics(1)); + manager.getMetrics(req); +} + +TEST_F(SolutionManagerSuite, CreateSolutionTest) { + Request req; + Header h1, h2, h3; + h1.name = "user_id"; + h1.value = "1"; + h2.name = "task_id"; + h2.value = "2"; + h3.name = "source"; + h3.value = "int main() { return 0; }"; + req.headers = {h1, h2, h3}; + EXPECT_CALL(*solutionService, createSolution(1, 2, "int main() { return 0; }")); + manager.createSolution(req); +} \ No newline at end of file diff --git a/server/internal/httpServer/tests/TaskManagerSuite.cpp b/server/internal/httpServer/tests/TaskManagerSuite.cpp new file mode 100644 index 0000000..f4822d2 --- /dev/null +++ b/server/internal/httpServer/tests/TaskManagerSuite.cpp @@ -0,0 +1,42 @@ +#include +#include + +#include "TaskManager.h" +#include "ITaskService.h" + +class TaskServiceMock : public ITaskService { +public: + TaskServiceMock() = default; + ~TaskServiceMock() = default; + + MOCK_METHOD(Task, createTask, (std::string desc), (override)); + MOCK_METHOD(Task, getTask, (size_t id), (override)); + MOCK_METHOD(std::vector, getAllTasks, (), (override)); + MOCK_METHOD(void, deleteTask, (size_t id), (override)); +}; + +class TaskManagerSuite : public ::testing::Test { +protected: + void SetUp() override { + manager.setService(taskService); + } + + std::shared_ptr taskService = std::make_shared(); + TaskManager manager; +}; + +TEST_F(TaskManagerSuite, CreateTaskTest) { + Request req; + Header h1, h2; + h1.name = "description"; + h1.value = "a"; + req.headers = {h1}; + EXPECT_CALL(*taskService, createTask("a")); + manager.createTask(req); +} + +TEST_F(TaskManagerSuite, GetAllTaskTest) { + Request req; + EXPECT_CALL(*taskService, getAllTasks); + manager.getAllTasks(req); +} \ No newline at end of file diff --git a/server/internal/httpServer/tests/UserManagerSuite.cpp b/server/internal/httpServer/tests/UserManagerSuite.cpp new file mode 100644 index 0000000..ad6b9d4 --- /dev/null +++ b/server/internal/httpServer/tests/UserManagerSuite.cpp @@ -0,0 +1,48 @@ +#include +#include + +#include "UserManager.h" +#include "IUserService.h" + +class UserServiceMock : public IUserService { +public: + UserServiceMock() = default; + ~UserServiceMock() = default; + MOCK_METHOD(User, createUser, (std::string login, std::string username, std::string password), (override)); + MOCK_METHOD(User, getUserById, (size_t id), (override)); + MOCK_METHOD(void, deleteUser, (size_t id), (override)); +}; + +class UserManagerSuite : public ::testing::Test { +protected: + void SetUp() override { + manager.setService(userService); + } + + std::shared_ptr userService = std::make_shared(); + UserManager manager; +}; + +TEST_F(UserManagerSuite, LoginUserTest) { + Request req; + Header h1, h2; + h1.name = "login"; + h1.value = 1; + req.headers = {h1}; + EXPECT_CALL(*userService, getUserById(1)); + manager.loginUser(req); +} + +TEST_F(UserManagerSuite, RgisterUserTest) { + Request req; + Header h1, h2, h3; + h1.name = "login"; + h1.value = "1"; + h2.name = "username"; + h2.value = "2"; + h3.name = "password"; + h3.value = "3"; + req.headers = {h1, h2, h3}; + EXPECT_CALL(*userService, createUser("1", "2", "3")); + manager.registerUser(req); +} \ No newline at end of file diff --git a/server/internal/httpServer/tests/main.cpp b/server/internal/httpServer/tests/main.cpp new file mode 100644 index 0000000..b8dd7bc --- /dev/null +++ b/server/internal/httpServer/tests/main.cpp @@ -0,0 +1,8 @@ +#include +#include + +int main(int argc, char** argv) { + ::testing::InitGoogleMock(&argc, argv); + + return RUN_ALL_TESTS(); +} \ No newline at end of file diff --git a/server/internal/httpServer/virtual/ISolutionManager.h b/server/internal/httpServer/virtual/ISolutionManager.h new file mode 100644 index 0000000..cd77215 --- /dev/null +++ b/server/internal/httpServer/virtual/ISolutionManager.h @@ -0,0 +1,17 @@ +#ifndef APP_HTTPSERVER_HTTPSERVER_MANAGERS_ISolutionMANAGER_H_ +#define APP_HTTPSERVER_HTTPSERVER_MANAGERS_ISolutionMANAGER_H_ + +#include +#include + +#include "Response.h" +#include "Request.h" + +class ISolutionManager { +public: + virtual Response getAllSolutions(const Request &req) = 0; + virtual Response createSolution(const Request &req) = 0; + virtual Response getMetrics(const Request &req) = 0; +}; + +#endif // APP_HTTPSERVER_HTTPSERVER_MANAGERS_ISolutionMANAGER_H_ diff --git a/server/internal/httpServer/virtual/ITaskManager.h b/server/internal/httpServer/virtual/ITaskManager.h new file mode 100644 index 0000000..11747f7 --- /dev/null +++ b/server/internal/httpServer/virtual/ITaskManager.h @@ -0,0 +1,17 @@ +#ifndef APP_HTTPSERVER_HTTPSERVER_MANAGERS_ITaskMANAGER_H_ +#define APP_HTTPSERVER_HTTPSERVER_MANAGERS_ITaskMANAGER_H_ + +#include +#include + +#include "Response.h" +#include "Request.h" +#include "Serializer.h" + +class ITaskManager { +public: + virtual Response createTask(const Request &req) = 0; + virtual Response getAllTasks(const Request &req) = 0; +}; + +#endif // APP_HTTPSERVER_HTTPSERVER_MANAGERS_ITaskMANAGER_H_ diff --git a/server/internal/httpServer/virtual/IUserManager.h b/server/internal/httpServer/virtual/IUserManager.h new file mode 100644 index 0000000..599a8ec --- /dev/null +++ b/server/internal/httpServer/virtual/IUserManager.h @@ -0,0 +1,17 @@ +#ifndef APP_HTTPSERVER_HTTPSERVER_MANAGERS_IUserMANAGER_H_ +#define APP_HTTPSERVER_HTTPSERVER_MANAGERS_IUserMANAGER_H_ + +#include +#include + +#include "Response.h" +#include "Request.h" +#include "Serializer.h" + +class IUserManager { +public: + virtual Response loginUser(const Request &req) = 0; + virtual Response registerUser(const Request &req) = 0; +}; + +#endif // APP_HTTPSERVER_HTTPSERVER_MANAGERS_IUserMANAGER_H_ -- GitLab