diff --git a/src/eedb/data/CategoriesModel.hpp b/src/eedb/data/CategoriesModel.hpp index ef923d1..2d8a018 100644 --- a/src/eedb/data/CategoriesModel.hpp +++ b/src/eedb/data/CategoriesModel.hpp @@ -3,8 +3,8 @@ #include -auto topLevelRows = 30; -auto secondLevelRows = 30; +auto topLevelRows = 300; +auto secondLevelRows = 300; namespace eedb { class CategoriesModel final : public Wt::WStandardItemModel { diff --git a/src/eedb/widgets/AuthWidget.cpp b/src/eedb/widgets/AuthWidget.cpp index 3786146..e39691d 100644 --- a/src/eedb/widgets/AuthWidget.cpp +++ b/src/eedb/widgets/AuthWidget.cpp @@ -10,7 +10,7 @@ namespace eedb { AuthPageImpl::AuthPageImpl(const auth::Services & baseAuth, std::unique_ptr< Wt::Auth::AbstractUserDatabase > userDatabase, Wt::Auth::Login & _login) - : _authWidget(new Wt::Auth::AuthWidget(*baseAuth.authService(), *userDatabase.get(), _login, nullptr)), + : _authWidget(std::make_unique< Wt::Auth::AuthWidget >(*baseAuth.authService(), *userDatabase.get(), _login, nullptr)), _userDatabase(std::move(userDatabase)) { _authWidget->model()->addPasswordAuth(eedb::auth::Services::passwordService()); _authWidget->model()->addOAuth(eedb::auth::Services::oAuthServices()); @@ -29,18 +29,14 @@ AuthPageImpl::AuthPageImpl(const auth::Services & baseAuth, }); } -AuthPageImpl::~AuthPageImpl() { - if(_authWidget && !_authWidget->parent()) - delete _authWidget; -} - +AuthPageImpl::~AuthPageImpl() = default; void AuthPageImpl::setParent(Wt::WContainerWidget * parent) { - parent->addWidget(_authWidget); + parent->addWidget(_authWidget.get()); } void AuthPageImpl::detachFrom(Wt::WContainerWidget * parent) { if(parent) - parent->removeWidget(_authWidget); + parent->removeWidget(_authWidget.get()); } void AuthPageImpl::processEnvironment() { diff --git a/src/eedb/widgets/AuthWidget.hpp b/src/eedb/widgets/AuthWidget.hpp index 52fafdc..332a11b 100644 --- a/src/eedb/widgets/AuthWidget.hpp +++ b/src/eedb/widgets/AuthWidget.hpp @@ -1,6 +1,8 @@ #pragma once #include +#include + namespace Wt { class WContainerWidget; } @@ -13,15 +15,37 @@ namespace eedb::auth { class Services; } +namespace std { + +template <> +struct default_delete< Wt::Auth::AuthWidget > { + void operator()(Wt::Auth::AuthWidget * ptr) { + if(ptr && !ptr->parent()) + delete ptr; + } +}; + +} + +// static_assert(std::is_base_of< Wt::WObject, Wt::Auth::AuthWidget >::value == true, ""); + +// template < typename T, typename... Args > +// unique_widget_ptr< T > make_unique_widget_ptr(Args &&... args) { +// return std::unique_ptr< T >(new T(std::forward< Args >(args)...), unique_widget_ptr< T >::deleter); +//} + +template < typename T > +void deleter(T * ptr) {} + namespace eedb { class AuthPage { public: virtual ~AuthPage() = default; - virtual void setParent(Wt::WContainerWidget * parent) = 0; - virtual void detachFrom(Wt::WContainerWidget * parent ) = 0; - virtual void processEnvironment() = 0; + virtual void setParent(Wt::WContainerWidget * parent) = 0; + virtual void detachFrom(Wt::WContainerWidget * parent) = 0; + virtual void processEnvironment() = 0; virtual Wt::Signals::connection registerNeedVerification(std::function< void() > f) { return _onNeedEmailVerification.connect([=](auto...) { f(); }); @@ -68,15 +92,13 @@ class AuthPageImpl final : public AuthPage { AuthPageImpl(const eedb::auth::Services & baseAuth, std::unique_ptr< Wt::Auth::AbstractUserDatabase > userDatabase, Wt::Auth::Login & session); - - ~AuthPageImpl(); - + ~AuthPageImpl(); void setParent(Wt::WContainerWidget * parent) override; - void detachFrom(Wt::WContainerWidget * parent ) override; - void processEnvironment() override; + void detachFrom(Wt::WContainerWidget * parent) override; + void processEnvironment() override; private: - Wt::Auth::AuthWidget *_authWidget; + std::unique_ptr< Wt::Auth::AuthWidget > _authWidget; std::unique_ptr< Wt::Auth::AbstractUserDatabase > _userDatabase; }; } diff --git a/src/eedb/widgets/HomePage.cpp b/src/eedb/widgets/HomePage.cpp index 6449b19..2113344 100644 --- a/src/eedb/widgets/HomePage.cpp +++ b/src/eedb/widgets/HomePage.cpp @@ -40,55 +40,54 @@ auto make_tree() { return tree; } -eedb::Home::Home(Session & session) : _session(session), _login(&_session.login()) {} - -void Home::show(Wt::WContainerWidget * container) { - // Create a navigation bar with a link to a web page. - auto navigation = new Wt::WNavigationBar(); - navigation->setTitle("eedb", "http://eedb.pl"); - navigation->setResponsive(true); +eedb::Home::Home(Session & session) : _session(session) {} +Wt::WNavigationBar * Home::createNavigationBar(Wt::WContainerWidget * container) { auto contentsStack = new Wt::WStackedWidget(container); contentsStack->addStyleClass("contents"); // Setup a Left-aligned menu. - Wt::WMenu * mainTabs = new Wt::WMenu(contentsStack); + auto mainTabs = new Wt::WMenu(contentsStack); mainTabs->addItem("Home"); - navigation->addMenu(mainTabs); - - // Setup a Right-aligned menu. - // Create a popup submenu for the Help menu. - auto popup = new Wt::WPopupMenu(); - popup->addItem("Contents"); - - auto help = new Wt::WMenuItem("Help"); - help->setMenu(popup); - - auto rightMenu = new Wt::WMenu(); - rightMenu->addItem(help); - navigation->addMenu(rightMenu, Wt::AlignRight); // Setup a Right-aligned menu. // Create a popup submenu for the Help menu. auto sessionMenuPopup = new Wt::WPopupMenu(); - sessionMenuPopup->addItem("Logout"); - sessionMenuPopup->setId("session.menu"); + sessionMenuPopup->setObjectName("home.navigation.session_menu_popup"); + sessionMenuPopup->addItem("Logout")->setObjectName("home.navigation.session_menu.logout"); - sessionMenuPopup->itemSelected().connect([=](auto...) { const_cast< Wt::Auth::Login * >(_login)->logout(); }); + sessionMenuPopup->itemSelected().connect([=](auto && item, auto...) { + Wt::log("notice") << item->objectName(); + const_cast< Wt::Auth::Login * >(&_session.login())->logout(); + }); auto sessionItem = new Wt::WMenuItem("Session"); + sessionItem->setObjectName("home.navigation.session_menu_item"); sessionItem->setMenu(sessionMenuPopup); auto sessionMenu = new Wt::WMenu(); + sessionMenu->setObjectName("home.navigation.session_menu"); sessionMenu->addItem(sessionItem); + + auto navigation = new Wt::WNavigationBar(); + navigation->setTitle("eedb", "http://eedb.pl"); + navigation->setResponsive(true); + navigation->addMenu(mainTabs, Wt::AlignLeft); navigation->addMenu(sessionMenu, Wt::AlignRight); + return navigation; +} + +void Home::show(Wt::WContainerWidget * container) { + // Create a navigation bar with a link to a web page. + auto navigation = createNavigationBar(container); + Wt::WVBoxLayout * vbox = new Wt::WVBoxLayout(); container->setLayout(vbox); - vbox->addWidget(navigation, 1); + vbox->addWidget(navigation, 0); Wt::WHBoxLayout * hbox = new Wt::WHBoxLayout(); - vbox->addLayout(hbox, 30); + vbox->addLayout(hbox, 10); Wt::WStackedWidget * contents = new Wt::WStackedWidget(); diff --git a/src/eedb/widgets/HomePage.hpp b/src/eedb/widgets/HomePage.hpp index 442eedc..3a7fed0 100644 --- a/src/eedb/widgets/HomePage.hpp +++ b/src/eedb/widgets/HomePage.hpp @@ -5,10 +5,7 @@ namespace Wt { class WContainerWidget; class WTreeView; -} - -namespace Wt::Auth { -class Login; +class WNavigationBar; } namespace eedb { @@ -30,9 +27,10 @@ class Home final : public HomePage { void show(Wt::WContainerWidget * parent) override; + Wt::WNavigationBar * createNavigationBar(Wt::WContainerWidget * container); + private: Session & _session; - const Wt::Auth::Login * _login; Wt::WTreeView * _categoryTree; }; } diff --git a/src/eedb/widgets/NavigationBar.cpp b/src/eedb/widgets/NavigationBar.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/eedb/widgets/NavigationBar.hpp b/src/eedb/widgets/NavigationBar.hpp new file mode 100644 index 0000000..1cb95ce --- /dev/null +++ b/src/eedb/widgets/NavigationBar.hpp @@ -0,0 +1,5 @@ +#pragma once + +namespace eedb { +class NavigationBar {}; +} diff --git a/tests/unit/test_eedb_application.cpp b/tests/unit/test_eedb_application.cpp index c23cfb2..2ac5ce8 100644 --- a/tests/unit/test_eedb_application.cpp +++ b/tests/unit/test_eedb_application.cpp @@ -57,6 +57,7 @@ class EedbApplicationTest : public Test { void expectCreateHomePage() { EXPECT_CALL(homePageFactory, impl()).WillOnce(Return(ByMove(homePage.getPtr()))); + EXPECT_CALL(*authPage, detachFrom(Ne(nullptr))); EXPECT_CALL(*homePage, show(_)); } diff --git a/tests/unit/test_eedb_authWidget.cpp b/tests/unit/test_eedb_authWidget.cpp index 66dea32..52c6507 100644 --- a/tests/unit/test_eedb_authWidget.cpp +++ b/tests/unit/test_eedb_authWidget.cpp @@ -1,14 +1,91 @@ -#include +#include -#include +#include "mocks/SessionMock.hpp" +#include "mocks/widgets/AuthPageMock.hpp" +#include "mocks/widgets/MainPageMock.hpp" +#include "utils/UniquePtrMockWrapper.hpp" #include +#include +#include -//TEST(a, b) { -// // Wt::Test::WTestEnvironment environment; -// // Wt::WApplication app(environment); +#include +#include +#include +#include +#include -// // BigWorkWidget * bw = new BigWorkWidget(app.root()); +class AuthPageFactory { + public: + MOCK_METHOD0(impl, std::unique_ptr< eedb::AuthPage >()); + auto operator()() { + return impl(); + } +}; + +using namespace testing; + +class EedbWidgetHomePageTest : public Test { + public: + EedbWidgetHomePageTest() { + createApp(); + expectCreateHomePage(); + authPage->notifyUserStrongLogin(); + } + + void createApp() { + expectCreateAuthPage(); + + auto session = std::make_unique< eedb::SessionMock >(); + // EXPECT_CALL(*session, login()).WillOnce(ReturnRef(login)); + + homePage = std::make_unique< eedb::Home >(*session); + sut = dynamic_cast< eedb::Home * >(homePage.get()); + + EXPECT_CALL(*session, enviroment()).WillOnce(ReturnRef(env)); + eedb = new eedb::EEDB(std::move(session), + [this]() { return authPageFactory(); }, + [&]() -> std::unique_ptr< eedb::HomePage > { return std::move(homePage); }); + } + void expectCreateAuthPage() { + EXPECT_CALL(authPageFactory, impl()).WillOnce(Return(ByMove(authPage.getPtr()))); + + EXPECT_CALL(*authPage, registerNeedVerification(_)).WillOnce(Invoke(authPage.get(), &eedb::AuthPageMock::regNeedEmailWerification)); + EXPECT_CALL(*authPage, registerOnUserWeakLogin(_)).WillOnce(Invoke(authPage.get(), &eedb::AuthPageMock::regWeakLogin)); + EXPECT_CALL(*authPage, registerOnUserStrongLogin(_)).WillOnce(Invoke(authPage.get(), &eedb::AuthPageMock::regStrongLogin)); + EXPECT_CALL(*authPage, registerOnUserLogout(_)).WillOnce(Invoke(authPage.get(), &eedb::AuthPageMock::regUserLogout)); + EXPECT_CALL(*authPage, setParent(Ne(nullptr))); + EXPECT_CALL(*authPage, processEnvironment()); + } + + void expectCreateHomePage() { + EXPECT_CALL(*authPage, detachFrom(Ne(nullptr))); + } + + protected: + Wt::Test::WTestEnvironment env; + Wt::Auth::Login login; + UniquePtrMockWrapper< eedb::AuthPageMock > authPage; + AuthPageFactory authPageFactory; + + std::unique_ptr< eedb::HomePage > homePage; + + eedb::EEDB * eedb; + + eedb::Home * sut; +}; + +TEST_F(EedbWidgetHomePageTest, createApp) { + auto menu = dynamic_cast< Wt::WPopupMenu * >(eedb->findWidget("home.navigation.session_menu_popup")); + auto menuItem = dynamic_cast< Wt::WMenuItem * >(eedb->findWidget("home.navigation.session_menu.logout")); + menu->triggered().emit(menuItem); +} + +// TEST(a, b) { +// auto session = std::make_unique< eedb::SessionMock >(); +// EXPECT_CALL(*session, enviroment()).WillOnce(ReturnRef(env)); + +// sut = new eedb::EEDB(std::move(session), [this]() { return authPageFactory(); }, [this]() { return homePageFactory(); }); // // Wt::WPushButton * b = dynamic_cast< Wt::WPushButton * >(app.findWidget("startbutton")); diff --git a/tests/unit/test_eedb_home_navigationBar.cpp b/tests/unit/test_eedb_home_navigationBar.cpp new file mode 100644 index 0000000..e69de29