#include "adminive/adapters/drogon.hpp" #include "adminive/adapters/nlohmann_json.hpp" #include #include #include #include #include namespace drogon_test { struct Config { std::string name{"default"}; }; struct Status { std::string user; }; } namespace adminive { template <> struct Type_Descriptor { static auto get() { using T = drogon_test::Config; return object("config", "Config", ADMINIVE_FIELD(T, name).editable().creatable()); } }; template <> struct Type_View_Descriptor { static Table_View table() { using T = drogon_test::Config; return table_view(column<&T::name>("Name").sort().search()); } }; template <> struct Type_Descriptor { static auto get() { using T = drogon_test::Status; return object("status", "Status", ADMINIVE_FIELD(T, user).label("User")); } }; } int main() { using Json = nlohmann::json; drogon_test::Config config; drogon::HttpAppFramework app; std::vector> tasks; std::string committed_user; adminive::Resource_Transaction transaction; transaction.commit = [&committed_user](const drogon_test::Config&, const adminive::Request_Context& context) { committed_user = context.user; }; adminive::Drogon_Bind_Options options; options.executor = [&tasks](std::function task) { tasks.push_back(std::move(task)); }; options.filters = {"LoginFilter", "AdminFilter"}; options.context_factory = [](const drogon::HttpRequestPtr& request) { adminive::Request_Context context; context.user = request->user; return context; }; { adminive::Drogon_Resource resource(config, "/config", std::move(transaction)); resource.bind(app, options); adminive::Drogon_Status_Resource status("/status", [](const adminive::Request_Context& context) { if(context.user == "error") { throw std::runtime_error("status failed"); } return drogon_test::Status{context.user}; }); status.bind(app, options); } assert(app.filters("/config/data", drogon::Post).size() == 2); assert(app.filters("/status/data", drogon::Get).size() == 2); auto request = std::make_shared(); drogon::HttpResponsePtr response; app.handle("/config/view", drogon::Get, request, [&response](const drogon::HttpResponsePtr& value) { response = value; }); assert(response->status == drogon::k200OK); assert(Json::parse(response->body).at("data").at("kind") == "form"); request->body = R"({"name":"updated"})"; request->user = "wyc"; response.reset(); app.handle("/config/data", drogon::Post, request, [&response](const drogon::HttpResponsePtr& value) { response = value; }); assert(!response); assert(tasks.size() == 1); tasks.front()(); tasks.erase(tasks.begin()); assert(response); assert(response->status == drogon::k200OK); assert(config.name == "updated"); assert(committed_user == "wyc"); response.reset(); app.handle("/status/data", drogon::Get, request, [&response](const drogon::HttpResponsePtr& value) { response = value; }); assert(!response); assert(tasks.size() == 1); tasks.front()(); tasks.erase(tasks.begin()); assert(response->status == drogon::k200OK); assert(Json::parse(response->body).at("data").at("user").at("value") == "wyc"); request->user = "error"; response.reset(); app.handle("/status/data", drogon::Get, request, [&response](const drogon::HttpResponsePtr& value) { response = value; }); tasks.front()(); tasks.erase(tasks.begin()); assert(response->status == drogon::k500InternalServerError); response.reset(); app.handle("/status/descriptor", drogon::Get, request, [&response](const drogon::HttpResponsePtr& value) { response = value; }); assert(response->status == drogon::k200OK); adminive::Drogon_Collection_Resource collection("/configs", {drogon_test::Config{"first"}}); collection.bind(app, options); response.reset(); app.handle("/configs/view", drogon::Get, request, [&response](const drogon::HttpResponsePtr& value) { response = value; }); assert(response->status == drogon::k200OK); assert(Json::parse(response->body).at("data").at("kind") == "table"); assert(Json::parse(response->body).at("data").at("columns").at(0).at("searchable") == true); request->parameters = {{"page", "1"}, {"perPage", "10"}, {"name", "fir"}}; response.reset(); app.handle("/configs", drogon::Get, request, [&response](const drogon::HttpResponsePtr& value) { response = value; }); assert(response->status == drogon::k200OK); assert(Json::parse(response->body).at("data").at("total") == 1); response.reset(); app.handle("/configs/1", drogon::Get, request, [&response](const drogon::HttpResponsePtr& value) { response = value; }); assert(response->status == drogon::k200OK); assert(Json::parse(response->body).at("data").at("name") == "first"); request->body = R"({"name":"second"})"; response.reset(); app.handle("/configs", drogon::Post, request, [&response](const drogon::HttpResponsePtr& value) { response = value; }); assert(!response); assert(tasks.size() == 1); tasks.front()(); tasks.erase(tasks.begin()); assert(response->status == drogon::k200OK); assert(collection.size() == 2); request->body = R"({"name":"changed"})"; response.reset(); app.handle("/configs/2", drogon::Patch, request, [&response](const drogon::HttpResponsePtr& value) { response = value; }); tasks.front()(); tasks.erase(tasks.begin()); assert(response->status == drogon::k200OK); assert(Json::parse(response->body).at("data").at("name") == "changed"); response.reset(); app.handle("/configs/1", drogon::Delete, request, [&response](const drogon::HttpResponsePtr& value) { response = value; }); tasks.front()(); tasks.erase(tasks.begin()); assert(response->status == drogon::k200OK); assert(collection.size() == 1); assert(app.filters("/configs/{1:id}", drogon::Patch).size() == 2); return 0; }