#include #include #include #include "core_response_generator.hpp" using namespace rublon; using namespace testing; namespace { Configuration conf; } class CoreHandlerMock : public CoreHandlerInterface< CoreHandlerMock > { public: CoreHandlerMock() {} MOCK_METHOD(( tl::expected< Document, CoreHandlerError > ), request, ( std::string_view, const Document & ), (const)); CoreHandlerMock & statusPending() { gen.status = "pending"; return *this; } CoreHandlerMock & brokenBody() { gen.generateBrokenData = true; return *this; } CoreHandlerMock & methods(std::initializer_list methods) { gen.methods(methods); return *this; } CoreHandlerMock & tid(std::string tid) { gen.tid(tid); return *this; } operator tl::expected< Document, CoreHandlerError >() { auto body = gen.generateBody(); rublon::Document doc; doc.Parse(body.c_str()); return doc; } auto create() { return static_cast< tl::expected< Document, CoreHandlerError > >(*this); } CoreResponseGenerator gen; }; class PamInfoMock { public: PamInfoMock(pam_handle_t *) {} MOCK_METHOD(rublon::NonOwningPtr< const char >, ip, (), (const)); MOCK_METHOD(rublon::NonOwningPtr< const char >, username, (), (const)); }; template < typename Pam > class MethodFactoryMock { public: using MethodFactoryCreate_t = tl::expected< Method, PamAction >; template MethodFactoryMock(Args && ... ) {} MOCK_METHOD(MethodFactoryCreate_t, create_mocked, (std::vector< std::string > methods, std::string tid), (const)); template < typename Array_t > MethodFactoryCreate_t create(const Array_t & methods, const std::string & tid) const { std::vector< std::string > _methods; std::transform(std::begin(methods), std::end(methods), std::back_inserter(_methods), [](const auto & el) { return std::string{el.GetString()}; }); return create_mocked(_methods, tid); } }; class InitTestable : public Init< MethodFactoryMock, PamInfoMock > { public: InitTestable(const rublon::Configuration & conf) : Init{nullptr, conf} {} PamInfoMock & pam() { return _pamInfo; } MethodFactoryMock & methodFactory(){ return _methodFactory; } }; class RublonHttpInitTest : public testing::Test { public: void expectDefaultPamInfo() { EXPECT_CALL(pam, ip()).WillOnce(Return("192.168.0.1")); EXPECT_CALL(pam, username()).WillOnce(Return("bwi")); } RublonHttpInitTest() : coreHandler{}, sut{conf}, pam{sut.pam()}, methodFactoryMock{sut.methodFactory()} { expectDefaultPamInfo(); } CoreHandlerMock coreHandler; InitTestable sut{conf}; PamInfoMock & pam; MethodFactoryMock &methodFactoryMock; }; using CoreReturn = tl::expected< Document, CoreHandlerError >; TEST_F(RublonHttpInitTest, initializationSendsRequestOnGoodPath) { EXPECT_CALL(coreHandler, request("/api/transaction/init", _)) .WillOnce(Return(tl::unexpected{CoreHandlerError{CoreHandlerError::BadSigature}})); sut.handle(coreHandler); } MATCHER_P(HoldsPamAction, action, "") { return not arg.has_value() && arg.error() == action; } TEST_F(RublonHttpInitTest, rublon_Accept_pamLoginWhenThereIsNoConnection) { EXPECT_CALL(coreHandler, request(_, _)).WillOnce(Return(tl::unexpected{CoreHandlerError{CoreHandlerError::ConnectionError}})); EXPECT_THAT(sut.handle(coreHandler), HoldsPamAction(PamAction::decline)); } TEST_F(RublonHttpInitTest, rublon_Decline_pamLoginWhenServerHasBadSignature) { EXPECT_CALL(coreHandler, request(_, _)).WillOnce(Return(tl::unexpected{CoreHandlerError{CoreHandlerError::BadSigature}})); EXPECT_THAT(sut.handle(coreHandler), HoldsPamAction(PamAction::decline)); } TEST_F(RublonHttpInitTest, rublon_Decline_pamLoginWhenServerReturnsBrokenData) { EXPECT_CALL(coreHandler, request(_, _)).WillOnce(Return(tl::unexpected{CoreHandlerError{CoreHandlerError::BrokenData}})); EXPECT_THAT(sut.handle(coreHandler), HoldsPamAction(PamAction::decline)); } TEST_F(RublonHttpInitTest, rublon_Decline_pamLoginWhenServerReturnsCoreException) { EXPECT_CALL(coreHandler, request(_, _)).WillOnce(Return(tl::unexpected{CoreHandlerError{CoreHandlerError::CoreException}})); EXPECT_THAT(sut.handle(coreHandler), HoldsPamAction(PamAction::decline)); } TEST_F(RublonHttpInitTest, AllNeededInformationNeedsToBePassedToMethodFactory) { EXPECT_CALL(coreHandler, request(_, _)).WillOnce(Return(coreHandler.statusPending().methods({"sms", "otp"}).tid("transaction ID").create())); EXPECT_CALL(methodFactoryMock, create_mocked(_,"transaction ID") ); sut.handle(coreHandler); }