diff options
-rw-r--r-- | gentoobrowse-api/service/Jamfile.jam | 1 | ||||
-rw-r--r-- | gentoobrowse-api/service/mailserverimpl.cpp | 64 | ||||
-rw-r--r-- | gentoobrowse-api/service/mailserverimpl.h | 20 | ||||
-rw-r--r-- | gentoobrowse-api/service/main.cpp | 16 | ||||
-rw-r--r-- | gentoobrowse-api/service/maintenanceCommon.cpp | 26 | ||||
-rw-r--r-- | gentoobrowse-api/service/notifications.ice | 35 | ||||
-rw-r--r-- | gentoobrowse-api/service/notificationsimpl.cpp | 8 | ||||
-rw-r--r-- | gentoobrowse-api/service/notificationsimpl.h | 6 | ||||
-rw-r--r-- | gentoobrowse-api/service/usersimpl.cpp | 11 | ||||
-rw-r--r-- | gentoobrowse-api/service/xsltStreamSerializer.cpp | 18 | ||||
-rw-r--r-- | gentoobrowse-api/service/xsltStreamSerializer.h | 8 | ||||
-rw-r--r-- | gentoobrowse-api/unittests/Jamfile.jam | 6 | ||||
-rw-r--r-- | gentoobrowse-api/unittests/mockDefs.cpp | 66 | ||||
-rw-r--r-- | gentoobrowse-api/unittests/mockDefs.h | 16 | ||||
-rw-r--r-- | gentoobrowse-api/unittests/mocks.ice | 15 | ||||
-rw-r--r-- | gentoobrowse-api/unittests/testNotifications.cpp | 79 | ||||
-rw-r--r-- | gentoobrowse-api/unittests/testNotificationsTriggers.cpp | 3 | ||||
-rw-r--r-- | gentoobrowse-api/unittests/testUsers.cpp | 7 |
18 files changed, 149 insertions, 256 deletions
diff --git a/gentoobrowse-api/service/Jamfile.jam b/gentoobrowse-api/service/Jamfile.jam index 04c9aa8..ed13895 100644 --- a/gentoobrowse-api/service/Jamfile.jam +++ b/gentoobrowse-api/service/Jamfile.jam @@ -51,6 +51,7 @@ lib gentoobrowse-service++11 : <icetray.sql.connector>postgresql <icetray.sql.basedir>. <include>. + <include>/usr/share/icetray/ice : : <include>. <implicit-dependency>../api//gentoobrowse-api diff --git a/gentoobrowse-api/service/mailserverimpl.cpp b/gentoobrowse-api/service/mailserverimpl.cpp deleted file mode 100644 index 8965c47..0000000 --- a/gentoobrowse-api/service/mailserverimpl.cpp +++ /dev/null @@ -1,64 +0,0 @@ -#include "mailserverimpl.h" -#include <libesmtp.h> -#include <Ice/ObjectAdapter.h> -#include <Ice/Communicator.h> - -namespace Gentoo { - namespace Service { - typedef std::vector<std::string> Parts; - typedef std::pair<Parts::iterator, Parts::const_iterator> PartsProgress; - - void - MailServer::sendEmail(Gentoo::EmailPtr msg, const Ice::Current & c) - { - auto props = c.adapter->getCommunicator()->getProperties(); - smtp_session_t session = smtp_create_session(); - smtp_message_t message = smtp_add_message(session); - auto server = props->getPropertyWithDefault("GentooBrowseAPI.MailServer", "localhost:25"); - smtp_set_server(session, server.c_str()); - smtp_set_header(message, "To", msg->to.name.c_str(), msg->to.address.c_str()); - smtp_set_header(message, "From", msg->from.name.c_str(), msg->from.address.c_str()); - smtp_set_header(message, "Subject", msg->subject.c_str()); - Parts parts; - parts.emplace_back("Content-Type: multipart/alternative; boundary=\"<<divider>>\"\r\n"); - parts.emplace_back("MIME-Version: 1.0\r\n"); - parts.emplace_back("Content-Transfer-Encoding: binary\r\n"); - smtp_add_recipient(message, msg->to.address.c_str()); - for (const auto & p : msg->body) { - parts.emplace_back("\r\n--<<divider>>\r\nContent-Type: " + p->mimetype + "; charset=\"utf-8\"\r\n\r\n"); - parts.emplace_back(p->payload); - } - parts.emplace_back("\r\n--<<divider>>--\r\n"); - PartsProgress pp { parts.begin(), parts.end() }; - smtp_set_messagecb(message, writeBody, &pp); - if (!smtp_start_session(session)) { - char buf[BUFSIZ]; - auto b = smtp_strerror(smtp_errno(), buf, sizeof(buf)); - assert(b); - SendEmailFailed e(b); - smtp_destroy_session(session); - throw e; - } - smtp_destroy_session(session); - } - - const char * - MailServer::writeBody(void **, int * len, void * arg) - { - auto parts = static_cast<PartsProgress *>(arg); - if (len == NULL || parts->first == parts->second) { - return NULL; - } - const auto & p = *parts->first++; - *len = p.length(); - return p.data(); - } - } - - void - SendEmailFailed::ice_print(std::ostream & buf) const - { - buf << "Failed to send email: " << message; - } -} - diff --git a/gentoobrowse-api/service/mailserverimpl.h b/gentoobrowse-api/service/mailserverimpl.h deleted file mode 100644 index d44d601..0000000 --- a/gentoobrowse-api/service/mailserverimpl.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef MAILSERVERIMPL_H -#define MAILSERVERIMPL_H - -#include <notifications.h> -#include <visibility.h> - -namespace Gentoo { - namespace Service { - class DLL_PUBLIC MailServer : public Gentoo::MailServer { - public: - void sendEmail(Gentoo::EmailPtr msg, const Ice::Current &) override; - - private: - static const char * writeBody(void ** buf, int * len, void * arg); - }; - } -} - -#endif - diff --git a/gentoobrowse-api/service/main.cpp b/gentoobrowse-api/service/main.cpp index e14c2a0..91ba9d4 100644 --- a/gentoobrowse-api/service/main.cpp +++ b/gentoobrowse-api/service/main.cpp @@ -1,11 +1,11 @@ #include <Ice/Initialize.h> -#include <Ice/ObjectAdapter.h> #include <icetrayService.h> #include "portageimpl.h" #include "usersimpl.h" #include "maintenanceimpl.h" #include "notificationsimpl.h" -#include "mailserverimpl.h" +#include "mailServer.h" +#include <icecube.h> #include <libexslt/exslt.h> #include <libxslt/transform.h> @@ -32,11 +32,13 @@ class Api : public IceTray::Service { void addObjects(const std::string &, const Ice::CommunicatorPtr & ic, const Ice::StringSeq &, const Ice::ObjectAdapterPtr & adp) override { auto db = getConnectionPool(ic, "postgresql", "GentooBrowseAPI"); - adp->add(std::make_shared<Portage>(db), Ice::stringToIdentity("portage")); - adp->add(std::make_shared<Maintenance>(db, ic, ic->getProperties()), Ice::stringToIdentity("maintenance")); - adp->add(std::make_shared<Users>(db), Ice::stringToIdentity("users")); - adp->add(std::make_shared<Notifications>(), Ice::stringToIdentity("notifications")); - adp->add(std::make_shared<MailServer>(), Ice::stringToIdentity("mailserver")); + auto props = ic->getProperties(); + IceTray::Cube::addObject<Gentoo::Portage, Portage>(adp, "portage", db); + IceTray::Cube::addObject<Gentoo::Maintenance, Maintenance>(adp, "maintenance", db, ic, props); + IceTray::Cube::addObject<Gentoo::Users, Users>(adp, "users", db); + IceTray::Cube::add<Gentoo::Notifications, Notifications>(); + IceTray::Cube::add<IceTray::Mail::MailServer, IceTray::Mail::LibesmtpMailServer>( + props->getPropertyWithDefault("GentooBrowseAPI.MailServer", "localhost:25")); } }; diff --git a/gentoobrowse-api/service/maintenanceCommon.cpp b/gentoobrowse-api/service/maintenanceCommon.cpp index 3fa81a1..7bcc195 100644 --- a/gentoobrowse-api/service/maintenanceCommon.cpp +++ b/gentoobrowse-api/service/maintenanceCommon.cpp @@ -5,6 +5,7 @@ #include <portage.h> #include <users.h> #include <safeMapFind.h> +#include <icecube.h> #include "sql/maintenance/getNotificationEbuildLists.sql.h" namespace Gentoo { @@ -15,15 +16,6 @@ namespace Gentoo { { } - protected: - template<typename Proxy> - auto - getProxy(const std::string & n) const { - auto p = Ice::checkedCast<Proxy>(ic->stringToProxy(n)); - p->ice_ping(); - return p; - } - private: Ice::CommunicatorPtr ic; }; @@ -33,7 +25,7 @@ namespace Gentoo { AutoUpdatePackages(Ice::CommunicatorPtr i) : BaseScheduledTask(i) { } void runTimerTask() override { - auto m = getProxy<MaintenancePrx>("maintenance"); + auto m = IceTray::Cube::get<Maintenance>(); auto rb = m->refreshBugsAsync(); m->updateRepositories(); m->refreshPackageTree(); @@ -47,7 +39,7 @@ namespace Gentoo { UserMaintenance(Ice::CommunicatorPtr i) : BaseScheduledTask(i) { } void runTimerTask() override { - auto u = getProxy<UsersPrx>("users"); + auto u = IceTray::Cube::get<Users>(); u->prune(); } }; @@ -90,9 +82,9 @@ namespace Gentoo { } Gentoo::UserNews - Maintenance::getUserNews(const Ice::Current & current) + Maintenance::getUserNews(const Ice::Current &) { - auto portage = Ice::checkedCast<PortagePrx>(current.adapter->getCommunicator()->stringToProxy("portage")); + auto portage = IceTray::Cube::get<Portage>(); portage->ice_ping(); auto categories = portage->getAllCategories(); @@ -120,11 +112,9 @@ namespace Gentoo { void Maintenance::sendNotifications(const Ice::Current & current) { - auto notifications = Ice::checkedCast<NotificationsPrx>(current.adapter->getCommunicator()->stringToProxy("notifications")); - notifications->ice_ping(); - auto mailServer = Ice::checkedCast<MailServerPrx>(current.adapter->getCommunicator()->stringToProxy("mailserver")); - mailServer->ice_ping(); - auto users = Ice::checkedCast<UsersPrx>(current.adapter->getCommunicator()->stringToProxy("users")); + auto notifications = IceTray::Cube::get<Notifications>(); + auto mailServer = IceTray::Cube::get<IceTray::Mail::MailServer>(); + auto users = IceTray::Cube::get<Users>(); users->ice_ping(); for (const auto & trigger : getUserNews(current)) { diff --git a/gentoobrowse-api/service/notifications.ice b/gentoobrowse-api/service/notifications.ice index 4a2673f..e020c39 100644 --- a/gentoobrowse-api/service/notifications.ice +++ b/gentoobrowse-api/service/notifications.ice @@ -1,41 +1,14 @@ #ifndef GENTOO_NOTIFICATIONS #define GENTOO_NOTIFICATIONS +#include <mail.ice> #include <user-models.ice> #include <news-models.ice> module Gentoo { - class MimePart { - string mimetype; - string payload; - }; - - sequence<MimePart> MimeParts; - - struct Address { - string name; - string address; - }; - - class Email { - Address to; - Address from; - string subject; - MimeParts body; - }; - - ["cpp:ice_print"] - exception SendEmailFailed { - string message; - }; - - interface Notifications { - Email getSignup(NewUser user); - Email getNews(User user, NewsContent nc); - }; - - interface MailServer { - idempotent void sendEmail(Email msg) throws SendEmailFailed; + local interface Notifications { + IceTray::Mail::Email getSignup(NewUser user); + IceTray::Mail::Email getNews(User user, NewsContent nc); }; }; diff --git a/gentoobrowse-api/service/notificationsimpl.cpp b/gentoobrowse-api/service/notificationsimpl.cpp index 64756bf..c15bc4f 100644 --- a/gentoobrowse-api/service/notificationsimpl.cpp +++ b/gentoobrowse-api/service/notificationsimpl.cpp @@ -30,23 +30,23 @@ namespace Gentoo { xsltSetLoaderFunc(NULL); } - Gentoo::EmailPtr Notifications::getSignup(Gentoo::NewUserPtr u, const Ice::Current &) + IceTray::Mail::EmailPtr Notifications::getSignup(const Gentoo::NewUserPtr & u) { auto e = basicMail("Welcome", u); Slicer::SerializeAny<XsltStreamSerializer>(u, e, signup.get()); return e; } - Gentoo::EmailPtr Notifications::getNews(Gentoo::UserPtr u, Gentoo::NewsContent c, const Ice::Current &) + IceTray::Mail::EmailPtr Notifications::getNews(const Gentoo::UserPtr & u, const Gentoo::NewsContent & c) { auto e = basicMail("Latest updates", u); Slicer::SerializeAny<XsltStreamSerializer>(c, e, news.get()); return e; } - Gentoo::EmailPtr Notifications::basicMail(const std::string & subject, Gentoo::UserPtr u) + IceTray::Mail::EmailPtr Notifications::basicMail(const std::string & subject, const Gentoo::UserPtr & u) { - Gentoo::EmailPtr e = std::make_shared<Gentoo::Email>(); + auto e = std::make_shared<IceTray::Mail::Email>(); e->subject = "Gentoo Browse: " + subject; e->from.name = "Gentoo Browse"; e->from.address = "noreply@gentoobrowse.randomdan.homeip.net"; diff --git a/gentoobrowse-api/service/notificationsimpl.h b/gentoobrowse-api/service/notificationsimpl.h index 762aa4a..9aef9f4 100644 --- a/gentoobrowse-api/service/notificationsimpl.h +++ b/gentoobrowse-api/service/notificationsimpl.h @@ -12,11 +12,11 @@ namespace Gentoo { public: Notifications(); - Gentoo::EmailPtr getSignup(Gentoo::NewUserPtr, const Ice::Current &) override; - Gentoo::EmailPtr getNews(Gentoo::UserPtr, Gentoo::NewsContent, const Ice::Current &) override; + IceTray::Mail::EmailPtr getSignup(const Gentoo::NewUserPtr &) override; + IceTray::Mail::EmailPtr getNews(const Gentoo::UserPtr &, const Gentoo::NewsContent &) override; private: - Gentoo::EmailPtr basicMail(const std::string &, Gentoo::UserPtr u); + IceTray::Mail::EmailPtr basicMail(const std::string &, const Gentoo::UserPtr & u); typedef std::shared_ptr<xsltStylesheet> xsltSSPtr; xsltSSPtr news; diff --git a/gentoobrowse-api/service/usersimpl.cpp b/gentoobrowse-api/service/usersimpl.cpp index e50076d..1b74dfd 100644 --- a/gentoobrowse-api/service/usersimpl.cpp +++ b/gentoobrowse-api/service/usersimpl.cpp @@ -15,6 +15,7 @@ #include <sql/users/tracked.sql.h> #include <sql/users/mailshotsent.sql.h> #include <notifications.h> +#include <icecube.h> namespace Gentoo { namespace Service { @@ -64,14 +65,10 @@ Users::authOrCreate(const std::string_view & username, const std::string_view & } Gentoo::NewUserPtr -Users::create(const std::string_view username, const std::string_view password, const std::string_view realname, const std::string_view email, const Ice::Current & current) +Users::create(const std::string_view username, const std::string_view password, const std::string_view realname, const std::string_view email, const Ice::Current &) { - auto notifications = Ice::checkedCast<NotificationsPrx>(current.adapter->getCommunicator()->stringToProxy("notifications")); - BOOST_ASSERT(notifications); - BOOST_ASSERT((notifications->ice_ping(), true)); - auto mailServer = Ice::checkedCast<MailServerPrx>(current.adapter->getCommunicator()->stringToProxy("mailserver")); - BOOST_ASSERT(mailServer); - BOOST_ASSERT((mailServer->ice_ping(), true)); + auto notifications = IceTray::Cube::get<Notifications>(); + auto mailServer = IceTray::Cube::get<IceTray::Mail::MailServer>(); auto dbc = db->get(); DB::TransactionScope tx(*dbc.get()); diff --git a/gentoobrowse-api/service/xsltStreamSerializer.cpp b/gentoobrowse-api/service/xsltStreamSerializer.cpp index abe652d..376d03e 100644 --- a/gentoobrowse-api/service/xsltStreamSerializer.cpp +++ b/gentoobrowse-api/service/xsltStreamSerializer.cpp @@ -4,8 +4,11 @@ #include <factory.impl.h> #include <processPipes.h> #include <sys/wait.h> +#include <mimeImpl.h> namespace Gentoo { + using namespace IceTray::Mime; + static int xmlstrmclosecallback(void * context) { ((std::ostream*)context)->flush(); @@ -18,7 +21,7 @@ namespace Gentoo { return len; } - XsltStreamSerializer::XsltStreamSerializer(Gentoo::EmailPtr e, xsltStylesheet * ss) : + XsltStreamSerializer::XsltStreamSerializer(const IceTray::Mail::EmailPtr & e, xsltStylesheet * ss) : Slicer::XmlDocumentSerializer(doc), mail(e), doc(nullptr), @@ -39,20 +42,21 @@ namespace Gentoo { if (!result) { throw xmlpp::exception("Failed to apply XSL transform"); } - appendText(result.get()); - appendHtml(result.get()); + mail->content = std::make_shared<MultiPart>(Headers {}, "alternative", Parts { + getText(result.get()), getHtml(result.get()) + }); } - void XsltStreamSerializer::appendHtml(xmlDoc * result) const + IceTray::Mime::BasicSinglePartPtr XsltStreamSerializer::getHtml(xmlDoc * result) { std::stringstream strm; xmlOutputBufferPtr buf = xmlOutputBufferCreateIO(xmlstrmwritecallback, xmlstrmclosecallback, &strm, NULL); htmlDocContentDumpFormatOutput(buf, result, "utf-8", 0); xmlOutputBufferClose(buf); - mail->body.push_back(std::make_shared<Gentoo::MimePart>("text/html", strm.str())); + return std::make_shared<TextPart>(Headers {}, "text/html", strm.str()); } - void XsltStreamSerializer::appendText(xmlDoc * result) const + IceTray::Mime::BasicSinglePartPtr XsltStreamSerializer::getText(xmlDoc * result) { std::stringstream strm; std::vector<std::string> callLynx; @@ -76,7 +80,7 @@ namespace Gentoo { if (status != 0) { throw std::runtime_error("Lynx failed"); } - mail->body.push_back(std::make_shared<Gentoo::MimePart>("text/plain", strm.str())); + return std::make_shared<TextPart>(Headers {}, "text/plain", strm.str()); } } diff --git a/gentoobrowse-api/service/xsltStreamSerializer.h b/gentoobrowse-api/service/xsltStreamSerializer.h index 492b954..7719856 100644 --- a/gentoobrowse-api/service/xsltStreamSerializer.h +++ b/gentoobrowse-api/service/xsltStreamSerializer.h @@ -9,16 +9,16 @@ namespace Gentoo { class DLL_PUBLIC XsltStreamSerializer : public Slicer::XmlDocumentSerializer { public: - XsltStreamSerializer(Gentoo::EmailPtr, xsltStylesheet *); + XsltStreamSerializer(const IceTray::Mail::EmailPtr &, xsltStylesheet *); ~XsltStreamSerializer(); void Serialize(Slicer::ModelPartForRootPtr mp) override; protected: - void appendHtml(xmlDoc *) const; - void appendText(xmlDoc *) const; + static IceTray::Mime::BasicSinglePartPtr getHtml(xmlDoc *); + static IceTray::Mime::BasicSinglePartPtr getText(xmlDoc *); - Gentoo::EmailPtr mail; + IceTray::Mail::EmailPtr mail; xmlpp::Document * doc; xsltStylesheet * stylesheet; }; diff --git a/gentoobrowse-api/unittests/Jamfile.jam b/gentoobrowse-api/unittests/Jamfile.jam index b765a6b..a1ad409 100644 --- a/gentoobrowse-api/unittests/Jamfile.jam +++ b/gentoobrowse-api/unittests/Jamfile.jam @@ -5,7 +5,8 @@ lib dbpp-postgresql : : : : <include>/usr/include/dbpp-postgresql ; lib dl ; lib git2 ; lib tidy ; -lib dryice : : : : <include>/usr/include/icetray ; +lib icetray : : : : <include>/usr/include/icetray ; +lib dryice : : : : <include>/usr/include/icetray <library>icetray ; path-constant me : . ; @@ -17,7 +18,6 @@ alias test-data : lib testCommon : mockDefs.cpp - mocks.ice : <library>dbpp-postgresql <library>..//dbppcore @@ -27,6 +27,7 @@ lib testCommon : <library>..//Ice <library>..//IceBox <library>dryice + <library>tidy <library>../service//gentoobrowse-service++11 <implicit-dependency>../service//gentoobrowse-service++11 <library>boost_utf @@ -133,7 +134,6 @@ run <dependency>../db/schema.sql <define>BOOST_TEST_DYN_LINK <library>testCommon - <library>tidy <implicit-dependency>testCommon : testNotifications ; diff --git a/gentoobrowse-api/unittests/mockDefs.cpp b/gentoobrowse-api/unittests/mockDefs.cpp index 16d8853..1c93246 100644 --- a/gentoobrowse-api/unittests/mockDefs.cpp +++ b/gentoobrowse-api/unittests/mockDefs.cpp @@ -1,18 +1,11 @@ #include "mockDefs.h" #include <definedDirs.h> #include <notifications.h> - -void -MockMailServerImpl::sendEmail(const Gentoo::EmailPtr e, const Ice::Current &) -{ - sentEmails.push_back(e); -} - -Gentoo::Emails -MockMailServerImpl::getSentEmails(const Ice::Current &) -{ - return sentEmails; -} +#include <tidy.h> +#include <fstream> +#include <mockMailServer.h> +#include <mimeImpl.h> +#include <icecube.h> Service::Service() : DB::PluginMock<PQ::Mock>("GentooBrowseAPI", { @@ -20,7 +13,7 @@ Service::Service() : rootDir / "data.sql" }, "user=postgres dbname=postgres") { - replace("mailserver", std::make_shared<MockMailServerImpl>()); + IceTray::DryIce::replace<IceTray::Mail::MailServer, IceTray::Mail::MockMailServerImpl>(); } Maintenance::Maintenance() : @@ -33,7 +26,7 @@ Maintenance::Maintenance() : rootDir.parent_path() / "db" / "schema.sql" }, "user=postgres dbname=postgres") { - replace("mailserver", std::make_shared<MockMailServerImpl>()); + IceTray::DryIce::replace<IceTray::Mail::MailServer, IceTray::Mail::MockMailServerImpl>(); } Mail::Mail() : @@ -44,11 +37,46 @@ Mail::Mail() : } TestClient::TestClient() : - m(getProxy<Gentoo::MaintenancePrx>("maintenance")), - p(getProxy<Gentoo::PortagePrx>("portage")), - n(getProxy<Gentoo::NotificationsPrx>("notifications")), - ms(getProxy<Gentoo::MailServerPrx>("mailserver")), - u(getProxy<Gentoo::UsersPrx>("users")) + m(IceTray::Cube::get<Gentoo::Maintenance>()), + p(IceTray::Cube::get<Gentoo::Portage>()), + n(IceTray::Cube::get<Gentoo::Notifications>()), + ms(IceTray::Cube::get<IceTray::Mail::MailServer>()), + u(IceTray::Cube::get<Gentoo::Users>()) { + BOOST_REQUIRE(m); + BOOST_REQUIRE(p); + BOOST_REQUIRE(n); + BOOST_REQUIRE(ms); + BOOST_REQUIRE(u); +} + +void +TestClient::lintable_test_files(std::string_view name, IceTray::Mail::EmailPtr e) +{ + BOOST_REQUIRE(e); + + std::ofstream text((binDir / name).replace_extension("txt")); + auto body = std::dynamic_pointer_cast<IceTray::Mime::BasicMultiPart>(e->content); + BOOST_REQUIRE(body); + BOOST_REQUIRE_EQUAL(2, body->parts.size()); + text << std::dynamic_pointer_cast<IceTray::Mime::TextPart>(body->parts[0])->payload; + + TidyDoc tdoc = tidyCreate(); + BOOST_REQUIRE_EQUAL(1, tidyOptSetBool(tdoc, TidyIndentContent, yes)); + BOOST_REQUIRE_EQUAL(1, tidyOptSetInt(tdoc, TidyWrapLen, 0)); + BOOST_REQUIRE_EQUAL(0, tidyParseString(tdoc, + std::dynamic_pointer_cast<IceTray::Mime::TextPart>(body->parts[1])->payload.c_str())); + BOOST_REQUIRE_EQUAL(0, tidyCleanAndRepair(tdoc)); + BOOST_REQUIRE_EQUAL(0, tidySaveFile(tdoc, (binDir / name).replace_extension(".html").c_str())); + BOOST_REQUIRE_EQUAL(0, tidyRunDiagnostics(tdoc)); + tidyRelease(tdoc); + + FILE * eml = fopen((binDir / name).replace_extension("eml").c_str(), "w"); + BOOST_REQUIRE(eml); + fputs("To: dan@randomdan.homeip.net\r\n", eml); + fputs("From: dan@randomdan.homeip.net\r\n", eml); + fputs("Return-path: <dan@randomdan.homeip.net>\r\n", eml); + fputs("Date: Tue, 7 May 2019 19:50:44 +0100\r\n", eml); + fclose(eml); } diff --git a/gentoobrowse-api/unittests/mockDefs.h b/gentoobrowse-api/unittests/mockDefs.h index 7ea3535..762a589 100644 --- a/gentoobrowse-api/unittests/mockDefs.h +++ b/gentoobrowse-api/unittests/mockDefs.h @@ -8,19 +8,9 @@ #include <users.h> #include <maintenance.h> #include <notifications.h> -#include <mocks.h> #include <selectcommandUtil.impl.h> #include <boost/test/unit_test.hpp> -class MockMailServerImpl : public Gentoo::MockMailServer { - public: - void sendEmail(const Gentoo::EmailPtr msg, const Ice::Current &) override; - Gentoo::Emails getSentEmails(const Ice::Current &) override; - - private: - Gentoo::Emails sentEmails; -}; - class DLL_PUBLIC Service : public IceTray::DryIce, DB::PluginMock<PQ::Mock> { public: Service(); @@ -42,9 +32,11 @@ class DLL_PUBLIC TestClient : public IceTray::DryIceClient { Gentoo::MaintenancePrxPtr m; Gentoo::PortagePrxPtr p; - Gentoo::NotificationsPrxPtr n; - Gentoo::MailServerPrxPtr ms; + Gentoo::NotificationsPtr n; + IceTray::Mail::MailServerPtr ms; Gentoo::UsersPrxPtr u; + + void lintable_test_files(std::string_view name, IceTray::Mail::EmailPtr e); }; #define SQL_REQUIRE_EQUAL(sql, type, expected) BOOST_TEST_CONTEXT(sql) { sqlRequireEqual<type>(db, sql, expected); } diff --git a/gentoobrowse-api/unittests/mocks.ice b/gentoobrowse-api/unittests/mocks.ice deleted file mode 100644 index f780d59..0000000 --- a/gentoobrowse-api/unittests/mocks.ice +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef GENTOO_MOCKS -#define GENTOO_MOCKS - -#include <notifications.ice> - -module Gentoo { - sequence<Email> Emails; - - interface MockMailServer extends MailServer { - Emails getSentEmails(); - }; -}; - -#endif - diff --git a/gentoobrowse-api/unittests/testNotifications.cpp b/gentoobrowse-api/unittests/testNotifications.cpp index 2783eb8..d961412 100644 --- a/gentoobrowse-api/unittests/testNotifications.cpp +++ b/gentoobrowse-api/unittests/testNotifications.cpp @@ -1,13 +1,17 @@ #define BOOST_TEST_MODULE TestNotifications #include <boost/test/unit_test.hpp> +#include <boost/test/data/test_case.hpp> #include "mockDefs.h" #include <definedDirs.h> #include <fstream> #include <regex> #include <tidy.h> +#include <mimeImpl.h> +#include <memstream.h> using namespace std::string_literals; +using QPTD = std::tuple<std::string_view, std::string_view>; BOOST_GLOBAL_FIXTURE( Mail ); @@ -20,38 +24,27 @@ isHtml(const std::string & body) } void -save(const std::string & name, Gentoo::EmailPtr e) +commonAssert(IceTray::Mail::EmailPtr e) { - std::ofstream text((binDir / (name + ".txt")).string()); - text << e->body[0]->payload; - - TidyDoc tdoc = tidyCreate(); - BOOST_REQUIRE_EQUAL(1, tidyOptSetBool(tdoc, TidyIndentContent, yes)); - BOOST_REQUIRE_EQUAL(1, tidyOptSetInt(tdoc, TidyWrapLen, 0)); - BOOST_REQUIRE_EQUAL(2, e->body.size()); - BOOST_REQUIRE_EQUAL(0, tidyParseString(tdoc, e->body[1]->payload.c_str())); - BOOST_REQUIRE_EQUAL(0, tidyCleanAndRepair(tdoc)); - BOOST_REQUIRE_EQUAL(0, tidySaveFile(tdoc, (binDir / name).replace_extension(".html").c_str())); - BOOST_REQUIRE_EQUAL(0, tidyRunDiagnostics(tdoc)); - tidyRelease(tdoc); -} - -void -commonAssert(Gentoo::EmailPtr e) -{ - BOOST_REQUIRE_EQUAL(e->body.size(), 2); - BOOST_REQUIRE_EQUAL(e->body[0]->mimetype, "text/plain"); - BOOST_REQUIRE(!isHtml(e->body[0]->payload)); - BOOST_REQUIRE_EQUAL(e->body[1]->mimetype, "text/html"); - BOOST_REQUIRE(isHtml(e->body[1]->payload)); - BOOST_REQUIRE_EQUAL(e->body[0]->payload.find("http://gentoobrowse.randomdan.homeip.net"), std::string::npos); - BOOST_REQUIRE_EQUAL(e->body[1]->payload.find("http://gentoobrowse.randomdan.homeip.net"), std::string::npos); - BOOST_REQUIRE_NE(e->body[1]->payload.find("https://cdnjs.cloudflare.com/"), std::string::npos); + auto body = std::dynamic_pointer_cast<IceTray::Mime::BasicMultiPart>(e->content); + BOOST_REQUIRE(body); + BOOST_REQUIRE_EQUAL(body->parts.size(), 2); + auto plain = std::dynamic_pointer_cast<IceTray::Mime::TextPart>(body->parts[0]); + BOOST_REQUIRE(plain); + BOOST_REQUIRE_EQUAL(plain->mimetype, "text/plain"); + BOOST_REQUIRE(!isHtml(plain->payload)); + auto html = std::dynamic_pointer_cast<IceTray::Mime::TextPart>(body->parts[1]); + BOOST_REQUIRE(html); + BOOST_REQUIRE_EQUAL(html->mimetype, "text/html"); + BOOST_REQUIRE(isHtml(html->payload)); + BOOST_REQUIRE_EQUAL(plain->payload.find("http://gentoobrowse.randomdan.homeip.net"), std::string::npos); + BOOST_REQUIRE_EQUAL(html->payload.find("http://gentoobrowse.randomdan.homeip.net"), std::string::npos); + BOOST_REQUIRE_NE(html->payload.find("https://cdnjs.cloudflare.com/"), std::string::npos); } -BOOST_AUTO_TEST_CASE( testSend ) +BOOST_AUTO_TEST_CASE( testSend, * boost::unit_test::disabled() ) { - Gentoo::NewUserPtr u = std::make_shared<Gentoo::NewUser>(1, "testuser", "Test User", "noone@randomdan.homeip.net", "2017-10-01T12:34:56", IceUtil::None, "some-guid"); + Gentoo::NewUserPtr u = std::make_shared<Gentoo::NewUser>(1, "testuser", "Test User", "dan@randomdan.homeip.net", "2017-10-01T12:34:56", IceUtil::None, "some-guid"); auto e = n->getSignup(u); BOOST_REQUIRE(e); ms->sendEmail(e); @@ -68,11 +61,15 @@ BOOST_AUTO_TEST_CASE( testSignup ) BOOST_REQUIRE_EQUAL(e->to.name, "Test User"); BOOST_REQUIRE_EQUAL(e->to.address, "test@user.com"); commonAssert(e); - save("signup", e); - for (auto p : e->body) { - BOOST_REQUIRE(p->payload.find("Welcome to Gentoo Browse") != std::string::npos); - BOOST_REQUIRE(p->payload.find("https://gentoobrowse.randomdan.homeip.net/user/verification/some-guid/testuser") != std::string::npos); - BOOST_REQUIRE(std::regex_search(p->payload, + lintable_test_files("signup", e); + auto body = std::dynamic_pointer_cast<IceTray::Mime::BasicMultiPart>(e->content); + BOOST_REQUIRE(body); + for (auto p : body->parts) { + auto text = std::dynamic_pointer_cast<IceTray::Mime::TextPart>(p); + BOOST_REQUIRE(text); + BOOST_REQUIRE(text->payload.find("Welcome to Gentoo Browse") != std::string::npos); + BOOST_REQUIRE(text->payload.find("https://gentoobrowse.randomdan.homeip.net/user/verification/some-guid/testuser") != std::string::npos); + BOOST_REQUIRE(std::regex_search(text->payload, std::regex("confirmation\\s+page:\\s+some-guid"))); } } @@ -104,12 +101,16 @@ BOOST_AUTO_TEST_CASE( testNews ) }; auto e = n->getNews(u, nc); commonAssert(e); - save("news", e); - for (auto p : e->body) { - BOOST_REQUIRE(p->payload.find("Latest news") != std::string::npos); - BOOST_REQUIRE(p->payload.find("https://gentoobrowse.randomdan.homeip.net/packages/app-test") != std::string::npos); - BOOST_REQUIRE(p->payload.find("https://gentoobrowse.randomdan.homeip.net/packages/app-test/app") != std::string::npos); - BOOST_REQUIRE(p->payload.find("no-show") == std::string::npos); + lintable_test_files("news", e); + auto body = std::dynamic_pointer_cast<IceTray::Mime::BasicMultiPart>(e->content); + BOOST_REQUIRE(body); + for (auto p : body->parts) { + auto text = std::dynamic_pointer_cast<IceTray::Mime::TextPart>(p); + BOOST_REQUIRE(text); + BOOST_REQUIRE(text->payload.find("Latest news") != std::string::npos); + BOOST_REQUIRE(text->payload.find("https://gentoobrowse.randomdan.homeip.net/packages/app-test") != std::string::npos); + BOOST_REQUIRE(text->payload.find("https://gentoobrowse.randomdan.homeip.net/packages/app-test/app") != std::string::npos); + BOOST_REQUIRE(text->payload.find("no-show") == std::string::npos); } } diff --git a/gentoobrowse-api/unittests/testNotificationsTriggers.cpp b/gentoobrowse-api/unittests/testNotificationsTriggers.cpp index 6455627..562f08a 100644 --- a/gentoobrowse-api/unittests/testNotificationsTriggers.cpp +++ b/gentoobrowse-api/unittests/testNotificationsTriggers.cpp @@ -2,6 +2,7 @@ #include <boost/test/unit_test.hpp> #include "mockDefs.h" +#include <mockMailServer.h> BOOST_GLOBAL_FIXTURE( Service ); @@ -33,7 +34,7 @@ BOOST_AUTO_TEST_CASE( triggers ) BOOST_AUTO_TEST_CASE( send ) { - auto ms = getProxy<Gentoo::MockMailServerPrx>("mailserver"); + auto ms = std::dynamic_pointer_cast<IceTray::Mail::MockMailServer>(this->ms); BOOST_REQUIRE(ms); BOOST_REQUIRE(!u->get(1)->lastmailshot); diff --git a/gentoobrowse-api/unittests/testUsers.cpp b/gentoobrowse-api/unittests/testUsers.cpp index 0c8683e..e3fb3c9 100644 --- a/gentoobrowse-api/unittests/testUsers.cpp +++ b/gentoobrowse-api/unittests/testUsers.cpp @@ -2,6 +2,7 @@ #include <boost/test/unit_test.hpp> #include "mockDefs.h" +#include <mockMailServer.h> BOOST_GLOBAL_FIXTURE( Service ); @@ -43,7 +44,9 @@ BOOST_AUTO_TEST_CASE( authenticateVerify ) BOOST_AUTO_TEST_CASE( create ) { - auto ms = getProxy<Gentoo::MockMailServerPrx>("mailserver"); + auto ms1 = IceTray::Cube::get<IceTray::Mail::MailServer>(); + BOOST_REQUIRE(ms1); + auto ms = std::dynamic_pointer_cast<IceTray::Mail::MockMailServer>(ms1); BOOST_REQUIRE(ms); auto user = u->create("testuser", "testpass", "Test User", "test@user.com"); BOOST_REQUIRE_EQUAL(1, ms->getSentEmails().size()); @@ -103,7 +106,7 @@ BOOST_AUTO_TEST_CASE( createAgain ) * * return original user * * resend verification */ - auto ms = getProxy<Gentoo::MockMailServerPrx>("mailserver"); + auto ms = std::dynamic_pointer_cast<IceTray::Mail::MockMailServerImpl>(this->ms); BOOST_REQUIRE(ms); auto user = u->create("testuser", "testpass", "Test User", "recreate@user.com"); BOOST_REQUIRE_EQUAL(2, ms->getSentEmails().size()); |