refactoring + add navigation bar class

This commit is contained in:
Wieczorek Bartosz 2017-03-21 12:22:19 +01:00
parent 512f9dc755
commit 4bcad2266b
10 changed files with 154 additions and 56 deletions

View File

@ -3,8 +3,8 @@
#include <boost/lexical_cast.hpp>
auto topLevelRows = 30;
auto secondLevelRows = 30;
auto topLevelRows = 300;
auto secondLevelRows = 300;
namespace eedb {
class CategoriesModel final : public Wt::WStandardItemModel {

View File

@ -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() {

View File

@ -1,6 +1,8 @@
#pragma once
#include <Wt/WSignal>
#include <Wt/Auth/AuthWidget>
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;
};
}

View File

@ -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();

View File

@ -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;
};
}

View File

View File

@ -0,0 +1,5 @@
#pragma once
namespace eedb {
class NavigationBar {};
}

View File

@ -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(_));
}

View File

@ -1,14 +1,91 @@
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include <eedb/EEDB.hpp>
#include "mocks/SessionMock.hpp"
#include "mocks/widgets/AuthPageMock.hpp"
#include "mocks/widgets/MainPageMock.hpp"
#include "utils/UniquePtrMockWrapper.hpp"
#include <Wt/Test/WTestEnvironment>
#include <Wt/WMenuItem>
#include <Wt/WPopupMenu>
//TEST(a, b) {
// // Wt::Test::WTestEnvironment environment;
// // Wt::WApplication app(environment);
#include <eedb/EEDB.hpp>
#include <eedb/Session.hpp>
#include <eedb/db/connection.hpp>
#include <eedb/widgets/HomePage.hpp>
#include <eedb/widgets/Theme.hpp>
// // 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"));