def test_get_statistics(self):
        share_repository_mock = mock.Mock()
        share_repository_mock.get_approved.side_effect = [
            'get_approved result'
        ]
        share_repository_mock.get_approved_count.side_effect = \
            ['get_approved_count result']
        share_repository_mock.get_paid_not_approved.side_effect = \
            ['get_paid_not_approved result']
        share_repository_mock.get_paid_not_approved_count.side_effect = \
            ['get_paid_not_approved_count result']

        share_information = ShareInformation(share_repository_mock)
        start_date = date(2017, 7, 19)
        end_date = date(2017, 7, 30)

        statistics = share_information.get_statistics(start_date, end_date)

        share_repository_mock.get_approved.assert_called_with(
            start_date, end_date)
        share_repository_mock.get_approved_count.assert_called_with(
            start_date, end_date)
        share_repository_mock.get_paid_not_approved.assert_called_with(
            start_date, end_date)
        share_repository_mock.get_paid_not_approved_count.assert_called_with(
            start_date, end_date)
        self.assertEqual(statistics['approved_shares'], 'get_approved result')
        self.assertEqual(statistics['approved_shares_count'],
                         'get_approved_count result')
        self.assertEqual(statistics['paid_not_approved_shares'],
                         'get_paid_not_approved result')
        self.assertEqual(statistics['paid_not_approved_shares_count'],
                         'get_paid_not_approved_count result')
    def test_delete(self):
        share_repository_mock = mock.Mock()
        share_repository_mock.delete.side_effect = ['delete result']

        share_information = ShareInformation(share_repository_mock)

        self.assertEqual(share_information.delete(2), 'delete result')
        share_repository_mock.delete.assert_called_with(2)
    def test_get(self):
        share_repository_mock = mock.Mock()
        share_repository_mock.get.side_effect = ['get result']

        share_information = ShareInformation(share_repository_mock)

        self.assertEqual(share_information.get(1), 'get result')
        share_repository_mock.get.assert_called_with(1)
예제 #4
0
    def test_get(self):
        share_repository_mock = mock.Mock()
        share_repository_mock.get.side_effect = ['get result']

        share_information = ShareInformation(share_repository_mock)

        self.assertEqual(share_information.get(1), 'get result')
        share_repository_mock.get.assert_called_with(1)
예제 #5
0
    def test_delete(self):
        share_repository_mock = mock.Mock()
        share_repository_mock.delete.side_effect = ['delete result']

        share_information = ShareInformation(share_repository_mock)

        self.assertEqual(share_information.delete(2), 'delete result')
        share_repository_mock.delete.assert_called_with(2)
    def test_get_member_shares(self):
        share_repository_mock = mock.Mock()
        share_repository_mock.get_member_shares.side_effect = [
            'get_member_shares result'
        ]

        share_information = ShareInformation(share_repository_mock)

        self.assertEqual(share_information.get_member_shares('ABCD1234'),
                         'get_member_shares result')
        share_repository_mock.get_member_shares.assert_called_with('ABCD1234')
예제 #7
0
    def test_get_member_shares(self):
        share_repository_mock = mock.Mock()
        share_repository_mock.get_member_shares.side_effect = [
            'get_member_shares result']

        share_information = ShareInformation(share_repository_mock)

        self.assertEqual(
            share_information.get_member_shares('ABCD1234'),
            'get_member_shares result')
        share_repository_mock.get_member_shares.assert_called_with('ABCD1234')
    def test_get_share_count(self):
        share_repository_mock = mock.Mock()
        share_repository_mock.get_share_count.side_effect = [
            'get_share_count result 1', 'get_share_count result 2'
        ]

        share_information = ShareInformation(share_repository_mock)

        self.assertEqual(share_information.get_share_count(),
                         'get_share_count result 1')
        share_repository_mock.get_share_count.assert_called_with(None)

        self.assertEqual(share_information.get_share_count(date(2017, 7, 20)),
                         'get_share_count result 2')
        share_repository_mock.get_share_count.assert_called_with(
            date(2017, 7, 20))
예제 #9
0
    def test_get_share_count(self):
        share_repository_mock = mock.Mock()
        share_repository_mock.get_share_count.side_effect = [
            'get_share_count result 1',
            'get_share_count result 2']

        share_information = ShareInformation(share_repository_mock)

        self.assertEqual(
            share_information.get_share_count(),
            'get_share_count result 1')
        share_repository_mock.get_share_count.assert_called_with(None)

        self.assertEqual(
            share_information.get_share_count(date(2017, 7, 20)),
            'get_share_count result 2')
        share_repository_mock.get_share_count.assert_called_with(
            date(2017, 7, 20))
    def test_get_member_share_count(self):
        share_repository_mock = mock.Mock()
        share_repository_mock.get_member_share_count.side_effect = [
            'get_member_share_count result 1',
            'get_member_share_count result 2'
        ]

        share_information = ShareInformation(share_repository_mock)

        self.assertEqual(share_information.get_member_share_count('ABCD1234'),
                         'get_member_share_count result 1')
        share_repository_mock.get_member_share_count.assert_called_with(
            'ABCD1234', None)

        self.assertEqual(
            share_information.get_member_share_count('WXYZ6789',
                                                     date(2017, 7, 20)),
            'get_member_share_count result 2')
        share_repository_mock.get_member_share_count.assert_called_with(
            'WXYZ6789', date(2017, 7, 20))
예제 #11
0
    def test_get_member_share_count(self):
        share_repository_mock = mock.Mock()
        share_repository_mock.get_member_share_count.side_effect = [
            'get_member_share_count result 1',
            'get_member_share_count result 2']

        share_information = ShareInformation(share_repository_mock)

        self.assertEqual(
            share_information.get_member_share_count('ABCD1234'),
            'get_member_share_count result 1')
        share_repository_mock.get_member_share_count.assert_called_with(
            'ABCD1234', None)

        self.assertEqual(
            share_information.get_member_share_count(
                'WXYZ6789', date(2017, 7, 20)),
            'get_member_share_count result 2')
        share_repository_mock.get_member_share_count.assert_called_with(
            'WXYZ6789', date(2017, 7, 20))
예제 #12
0
    def test_get_statistics(self):
        share_repository_mock = mock.Mock()
        share_repository_mock.get_approved.side_effect = ['get_approved result']
        share_repository_mock.get_approved_count.side_effect = \
            ['get_approved_count result']
        share_repository_mock.get_paid_not_approved.side_effect = \
            ['get_paid_not_approved result']
        share_repository_mock.get_paid_not_approved_count.side_effect = \
            ['get_paid_not_approved_count result']

        share_information = ShareInformation(share_repository_mock)
        start_date = date(2017, 7, 19)
        end_date = date(2017, 7, 30)

        statistics = share_information.get_statistics(start_date, end_date)

        share_repository_mock.get_approved.assert_called_with(
            start_date, end_date)
        share_repository_mock.get_approved_count.assert_called_with(
            start_date, end_date)
        share_repository_mock.get_paid_not_approved.assert_called_with(
            start_date, end_date)
        share_repository_mock.get_paid_not_approved_count.assert_called_with(
            start_date, end_date)
        self.assertEqual(
            statistics['approved_shares'],
            'get_approved result')
        self.assertEqual(
            statistics['approved_shares_count'],
            'get_approved_count result')
        self.assertEqual(
            statistics['paid_not_approved_shares'],
            'get_paid_not_approved result')
        self.assertEqual(
            statistics['paid_not_approved_shares_count'],
            'get_paid_not_approved_count result')
예제 #13
0
def main(global_config, **settings):
    """ This function returns a Pyramid WSGI application.
    """
    engine = engine_from_config(settings, 'sqlalchemy.')
    session_factory = session_factory_from_settings(settings)

    authn_policy = AuthTktAuthenticationPolicy(
        's0secret!!',
        callback=groupfinder,
    )
    authz_policy = ACLAuthorizationPolicy()

    Base.metadata.bind = engine

    config = Configurator(settings=settings,
                          authentication_policy=authn_policy,
                          authorization_policy=authz_policy,
                          session_factory=session_factory,
                          root_factory=Root)

    # using a custom request with user information
    config.set_request_factory(RequestWithUserAttribute)
    config.set_locale_negotiator(enforcing_locale_negotiator)

    config.include('pyramid_mailer')
    config.include('pyramid_chameleon')
    config.include('cornice')
    config.include('c3smembership.presentation.pagination')

    config.add_translation_dirs('colander:locale/', 'deform:locale/',
                                'c3smembership:../customization/locale/')

    config.add_static_view('static_deform', 'deform:static')
    config.add_static_view('static',
                           'c3smembership:static',
                           cache_max_age=3600)
    config.add_static_view('docs', '../docs/_build/html/', cache_max_age=3600)

    config.add_subscriber('c3smembership.subscribers.add_base_template',
                          'pyramid.events.BeforeRender')
    config.add_subscriber(
        'c3smembership.subscribers.add_base_bootstrap_template',
        'pyramid.events.BeforeRender')
    config.add_subscriber('c3smembership.subscribers.add_backend_template',
                          'pyramid.events.BeforeRender')
    config.add_subscriber('c3smembership.subscribers.add_locale_to_cookie',
                          'pyramid.events.NewRequest')
    config.add_renderer(name='csv',
                        factory='c3smembership.renderers.CSVRenderer')

    from c3smembership.data.repository.share_repository import ShareRepository
    from c3smembership.business.share_acquisition import ShareAcquisition
    share_acquisition = ShareAcquisition(ShareRepository)
    config.registry.share_acquisition = share_acquisition

    # Membership application process
    # Step 1 (join.pt): home is /, the membership application form
    config.add_route('join', '/')
    # Step 2 (success.pt): check and edit data
    config.add_route('success', '/success')
    # Step 3 email was sent (check-mail.pt): send verification email address
    config.add_route('success_check_email', '/check_email')
    # Still step 3 (verify_password.pt): enter password
    # and step 4 (verify_password.pt): download form
    config.add_route('verify_email_password', '/verify/{email}/{code}')  # PDF
    # PDF download of Step 4.
    config.add_route('success_pdf', '/C3S_SCE_AFM_{namepart}.pdf')  # download
    # confirm email address later (30c3 cases)
    config.add_route('verify_afm_email',
                     '/vae/{refcode}/{token}/{email}')  # verify afm email

    # applications for membership
    config.add_route('dashboard', '/dashboard')
    config.make_pagination_route('dashboard',
                                 dashboard_content_size_provider,
                                 sort_property_default='id',
                                 page_size_default=int(
                                     settings.get(
                                         'c3smembership.dashboard_number',
                                         30)))

    config.add_route('dash', '/dash/{number}/{orderby}/{order}')
    config.add_route('toolbox', '/toolbox')
    config.add_route('stats', '/stats')
    config.add_route('staff', '/staff')
    config.add_route('new_member', '/new_member')
    config.add_route('detail', '/detail/{memberid}')
    config.add_route('edit', '/edit/{_id}')

    # TODO: move application layer setup to separate module
    from c3smembership.data.repository.member_repository import (
        MemberRepository)
    from c3smembership.business.membership_application import (
        MembershipApplication)
    membership_application = MembershipApplication(MemberRepository)
    config.registry.membership_application = membership_application
    config.add_route('switch_sig', '/switch_sig/{memberid}')
    config.add_route('switch_pay', '/switch_pay/{memberid}')

    config.add_route('mail_sig_confirmation', '/mail_sig_conf/{memberid}')
    config.add_route('regenerate_pdf', '/re_C3S_SCE_AFM_{code}.pdf')
    config.add_route('mail_pay_confirmation', '/mail_pay_conf/{member_id}')
    config.add_route('mail_mail_confirmation', '/mail_mail_conf/{memberid}')
    config.add_route('mail_sig_reminder', '/mail_sig_reminder/{memberid}')
    config.add_route('mail_pay_reminder', '/mail_pay_reminder/{memberid}')
    config.add_route('delete_entry', '/delete/{memberid}')
    config.add_route('delete_afms', '/delete_afms')
    config.add_route('login', '/login')
    config.add_route('logout', '/logout')

    # gather missing information
    config.add_route('mail_mtype_form', '/mtype/{afmid}')  # mail link to form
    config.add_route('mtype_form', '/mtype/{refcode}/{token}/{email}')  # form
    config.add_route('mtype_thanks', '/mtype_thanks')  # thanks

    # applications for membership
    config.add_route('afms_awaiting_approval', '/afms_awaiting_approval')

    # memberships
    config.add_route('make_member', '/make_member/{afm_id}')
    config.add_route('merge_member', '/merge_member/{afm_id}/{mid}')

    config.add_route('membership_listing_backend', '/memberships')
    config.make_pagination_route('membership_listing_backend',
                                 membership_content_size_provider,
                                 sort_property_default='id',
                                 page_size_default=int(
                                     settings.get(
                                         'c3smembership.membership_number',
                                         30)))

    config.add_route('membership_listing_alphabetical', '/aml')

    # membership list
    from c3smembership.data.repository.member_repository import (
        MemberRepository)
    from c3smembership.business.member_information import MemberInformation
    config.registry.member_information = MemberInformation(MemberRepository)

    config.add_route('membership_listing_date_pdf', '/aml-{date}.pdf')

    config.add_route('membership_listing_aufstockers', '/aml_aufstockers')

    # membership dues 2015
    config.add_route('send_dues15_invoice_email',
                     '/dues15_invoice/{member_id}')
    config.add_route('send_dues15_invoice_batch', '/dues15_invoice_batch')
    config.add_route('make_dues15_invoice_no_pdf',
                     '/dues15_invoice_no/{code}/C3S-dues15-{i}.pdf')
    # for backward compatibility
    config.add_route('make_dues15_invoice_no_pdf_email',
                     '/dues15_invoice_no/{email}/{code}/C3S-dues15-{i}.pdf')
    config.add_route('dues15_reduction', '/dues15_reduction/{member_id}')
    config.add_route('make_dues15_reversal_invoice_pdf',
                     '/dues15_reversal/{code}/C3S-dues15-{no}-S.pdf')
    # for backward compatibility
    config.add_route('make_dues15_reversal_invoice_pdf_email',
                     '/dues15_reversal/{email}/{code}/C3S-dues15-{no}-S.pdf')
    config.add_route('dues15_notice', '/dues15_notice/{member_id}')
    config.add_route('dues15_listing', '/dues15_listing')

    # membership dues 2016
    config.add_route('send_dues16_invoice_email',
                     '/dues16_invoice/{member_id}')
    config.add_route('send_dues16_invoice_batch', '/dues16_invoice_batch')
    config.add_route('make_dues16_invoice_no_pdf',
                     '/dues16_invoice_no/{code}/C3S-dues16-{i}.pdf')
    # for backward compatibility
    config.add_route('make_dues16_invoice_no_pdf_email',
                     '/dues16_invoice_no/{email}/{code}/C3S-dues16-{i}.pdf')
    config.add_route('dues16_reduction', '/dues16_reduction/{member_id}')
    config.add_route('make_dues16_reversal_invoice_pdf',
                     '/dues16_reversal/{code}/C3S-dues16-{no}-S.pdf')
    # for backward compatibility
    config.add_route('make_dues16_reversal_invoice_pdf_email',
                     '/dues16_reversal/{email}/{code}/C3S-dues16-{no}-S.pdf')
    config.add_route('dues16_notice', '/dues16_notice/{member_id}')
    config.add_route('dues16_listing', '/dues16_listing')

    # membership dues 2017
    config.add_route('send_dues17_invoice_email',
                     '/dues17_invoice/{member_id}')
    config.add_route('send_dues17_invoice_batch', '/dues17_invoice_batch')
    config.add_route('make_dues17_invoice_no_pdf',
                     '/dues17_invoice_no/{code}/C3S-dues17-{i}.pdf')
    config.add_route('dues17_reduction', '/dues17_reduction/{member_id}')
    config.add_route('make_dues17_reversal_invoice_pdf',
                     '/dues17_reversal/{code}/C3S-dues17-{no}-S.pdf')
    config.add_route('dues17_notice', '/dues17_notice/{member_id}')
    config.add_route('dues17_listing', '/dues17_listing')

    # TODO: move application layer setup to separate module
    from c3smembership.models import C3sMember
    from c3smembership.models import Dues15Invoice
    from c3smembership.data.model.base import DBSession
    from c3smembership.business.dues_invoice_archiving import (
        DuesInvoiceArchiving)
    from c3smembership.views.membership_dues import (
        make_invoice_pdf_pdflatex,
        make_reversal_pdf_pdflatex,
    )
    invoices_archive_path = os.path.abspath(
        os.path.join(os.path.dirname(os.path.abspath(__file__)),
                     '../invoices/'))
    config.registry.dues_invoice_archiving = DuesInvoiceArchiving(
        DBSession, C3sMember, Dues15Invoice, make_invoice_pdf_pdflatex,
        make_reversal_pdf_pdflatex, invoices_archive_path)
    config.add_route('batch_archive_pdf_invoices',
                     '/batch_archive_pdf_invoices')

    # utilities & wizardry
    config.add_route('plz_dist', '/plz_dist')
    config.add_route('get_member', '/members/{member_id}')
    config.add_route('error_page', '/error')  # generic error view

    # shares
    config.add_route('shares_detail', '/shares_detail/{id}')
    config.add_route('shares_edit', '/shares_edit/{id}')
    config.add_route('shares_delete', '/shares_delete/{id}')

    # membership_certificate
    config.add_route('certificate_mail', '/cert_mail/{id}')
    config.add_route('certificate_pdf', '/cert/{id}/C3S_{name}_{token}.pdf')
    config.add_route('certificate_pdf_staff', '/cert/{id}/C3S_{name}.pdf')

    # annual reports
    from c3smembership.data.repository.share_repository import ShareRepository
    from c3smembership.business.share_information import ShareInformation
    config.registry.share_information = ShareInformation(ShareRepository)
    config.add_route('annual_reporting', '/annual_reporting')

    # invite people
    config.add_route('invite_member', '/invite_member/{m_id}')
    config.add_route('invite_batch', '/invite_batch/{number}')

    # search for people
    config.add_route('search_people', '/search_people')
    config.add_route('autocomplete_people_search', '/aps/')

    # search for codes
    config.add_route('search_codes', '/search_codes')
    config.add_route('autocomplete_input_values', '/aiv/')

    config.scan()
    return config.make_wsgi_app()