Exemplo n.º 1
0
    def test_dues15_reduction(self):
        """
        test the dues15_reduction functionality
        """
        # have to accept their membersip first
        m1 = C3sMember.get_by_id(1)  # german normal member
        m1.membership_accepted = True
        m2 = C3sMember.get_by_id(2)  # english normal member
        m2.membership_accepted = True

        self.config.add_route('make_dues15_invoice_no_pdf', '/')
        self.config.add_route('make_dues15_reversal_invoice_pdf', '/')
        self.config.add_route('detail', '/detail/')
        self.config.add_route('error_page', '/error_page')
        self.config.add_route('toolbox', '/toolbox')
        req = testing.DummyRequest()
        req.referrer = 'toolbox'
        from c3smembership.views.membership_dues import send_dues15_invoice_batch
        # send out invoices. this is a prerequisite for reductions
        res = send_dues15_invoice_batch(req)
        res
        """
        test reduction of dues
        """
        # pre-check
        self.assertFalse(m1.dues15_reduced)  # not reduced yet!
        _m1_amount_reduced = m1.dues15_amount_reduced  # is Decimal('0')
        _number_of_invoices_before_reduction = len(Dues15Invoice.get_all())
        # print("_number_of_invoices_before_reduction: {}".format(
        #    _number_of_invoices_before_reduction))
        # we have 2 invoices as of now
        self.assertEqual(len(Dues15Invoice.get_all()), 2)
        # import the function under test
        from c3smembership.views.membership_dues import dues15_reduction

        #############################################################
        # try to reduce to the given calculated amount (edge case coverage)
        # this will not work, produce no new invoices
        req_reduce = testing.DummyRequest(  # prepare request
            post={
                'confirmed': 'yes',
                'submit': True,
                'amount': 50,
            },
        )
        req_reduce.matchdict['member_id'] = 1  # do it for member with id 1

        res_reduce = dues15_reduction(req_reduce)  # call reduce on her

        self.assertEqual(len(Dues15Invoice.get_all()), 2)  # no new invoice

        #############################################################
        # try to reduce above the given calculated amount
        # this will not work, produce no new invoices
        req_reduce = testing.DummyRequest(  # prepare request
            post={
                'confirmed': 'yes',
                'submit': True,
                'amount': 500,
            },
        )
        req_reduce.matchdict['member_id'] = 1  # do it for member with id 1

        res_reduce = dues15_reduction(req_reduce)  # call reduce on her

        self.assertEqual(len(Dues15Invoice.get_all()), 2)  # no new invoice

        #############################################################
        # valid reduction but without confirmation
        req_reduce = testing.DummyRequest(
            post={
                'confirmed': 'no',
                'submit': True,
                'amount': 42,
            },
        )
        req_reduce.matchdict['member_id'] = 1
        res_reduce = dues15_reduction(req_reduce)
        self.assertEqual(len(Dues15Invoice.get_all()), 2)  # no new invoice

        #############################################################
        # valid reduction
        req_reduce = testing.DummyRequest(
            post={
                'confirmed': 'yes',
                'submit': True,
                'amount': 42,
            },
        )
        req_reduce.matchdict['member_id'] = 1
        res_reduce = dues15_reduction(req_reduce)

        _number_of_invoices_after_reduction = len(Dues15Invoice.get_all())

        assert(  # two new invoices must have been issued
            (_number_of_invoices_before_reduction + 2) ==
            _number_of_invoices_after_reduction)
        assert(_number_of_invoices_after_reduction == 4)
        assert('detail' in res_reduce.headers['Location'])  # 302 to detail p.
        assert(_m1_amount_reduced != m1.dues15_amount_reduced)  # changed!
        assert(m1.dues15_amount_reduced == 42)  # changed to 42!

        # check the invoice created
        _rev_inv = Dues15Invoice.get_by_invoice_no(
            _number_of_invoices_before_reduction + 1)
        _new_inv = Dues15Invoice.get_by_invoice_no(
            _number_of_invoices_before_reduction + 2)
        # print(_rev_inv.invoice_amount)
        # print(type(_rev_inv.invoice_amount))
        assert(_rev_inv.invoice_amount == D('-50'))
        assert(_new_inv.invoice_amount == D('42'))

        # we have 4 invoices as of now
        self.assertEqual(len(Dues15Invoice.get_all()), 4)

        #############################################################
        # now try to raise above the previous reduction
        req_reduce = testing.DummyRequest(
            post={
                'confirmed': 'yes',
                'submit': True,
                'amount': 50,
            },
        )
        req_reduce.matchdict['member_id'] = 1
        res_reduce = dues15_reduction(req_reduce)

        _number_of_invoices_after_reduction = len(Dues15Invoice.get_all())

        # no new invoices were created, we still have 4 invoices
        self.assertEqual(len(Dues15Invoice.get_all()), 4)

        #############################################################
        # try to reduce to the same amount again (edge case coverage)
        req_reduce = testing.DummyRequest(
            post={
                'confirmed': 'yes',
                'submit': True,
                'amount': 42,
                # lots of values missing
            },
        )
        req_reduce.matchdict['member_id'] = 1
        res_reduce = dues15_reduction(req_reduce)
        #############################################################
        # try to reduce to zero (edge case coverage)
        # print("------------- reduction to zero ahead!!!")
        req_reduce = testing.DummyRequest(
            post={
                'confirmed': 'yes',
                'submit': True,
                'amount': 0,
                # lots of values missing
            },
        )
        req_reduce.matchdict['member_id'] = 1
        res_reduce = dues15_reduction(req_reduce)

        req_reduce = testing.DummyRequest(
            post={
                'confirmed': 'yes',
                'submit': True,
                'amount': 0,
                # lots of values missing
            },
        )
        req_reduce.matchdict['member_id'] = 2
        res_reduce = dues15_reduction(req_reduce)
        #############################################################
        # try to reduce to zero with english member (edge case coverage)
        # how to do this if you already reduced to zero? reduce to more first!
        req_reduce = testing.DummyRequest(
            post={
                'confirmed': 'yes',
                'submit': True,
                'amount': 1,
                # lots of values missing
            },
        )
        req_reduce.matchdict['member_id'] = 1
        res_reduce = dues15_reduction(req_reduce)
        m1.locale = u'en'
        req_reduce = testing.DummyRequest(
            post={
                'confirmed': 'yes',
                'submit': True,
                'amount': 0,
                # lots of values missing
            },
        )
        req_reduce.matchdict['member_id'] = 1
        res_reduce = dues15_reduction(req_reduce)
        #############################################################
        """
        test reversal invoice PDF generation
        """

        from c3smembership.views.membership_dues import (
            make_dues15_reversal_invoice_pdf)
        req2 = testing.DummyRequest()

        # wrong token: must fail!
        req2.matchdict = {
            'email': m1.email,
            'code': m1.dues15_token + 'false!!!',  # must fail
            'no': u'0006',
        }
        res = make_dues15_reversal_invoice_pdf(req2)
        assert('application/pdf' not in res.headers['Content-Type'])  # no PDF
        assert('error_page' in res.headers['Location'])  # but error

        # wrong invoice number: must fail!
        req2.matchdict = {
            'email': m1.email,
            'code': m1.dues15_token,
            'no': u'1234',  # must fail
        }
        res = make_dues15_reversal_invoice_pdf(req2)
        assert('application/pdf' not in res.headers['Content-Type'])  # no PDF
        assert('error_page' in res.headers['Location'])  # but error

        # wrong invoice token: must fail!
        i2 = Dues15Invoice.get_by_invoice_no('2')
        i2.token = u'not_matching'
        req2.matchdict = {
            'email': m2.email,
            'code': m2.dues15_token,
            'no': u'2',  # must fail
        }
        res = make_dues15_reversal_invoice_pdf(req2)
        assert('application/pdf' not in res.headers['Content-Type'])  # no PDF
        assert('error_page' in res.headers['Location'])  # but error

        ######################################################################
        # wrong invoice type (not a reversal): must fail! (edge case coverage)
        assert(not i2.is_reversal)  # i2 is not a reversal
        i2.token = m2.dues15_token  # we give it a valid token
        req2.matchdict = {
            'email': m2.email,
            'code': m2.dues15_token,
            'no': u'0002',
        }
        res = make_dues15_reversal_invoice_pdf(req2)
        assert('application/pdf' not in res.headers['Content-Type'])  # no PDF
        assert('error_page' in res.headers['Location'])  # but error
        ######################################################################

        # retry with valid token:
        req2.matchdict = {
            'email': m1.email,
            'code': m1.dues15_token,
            'no': u'0003',
        }
        res = make_dues15_reversal_invoice_pdf(req2)
        # print("length of the result: {}".format(len(res.body)))
        # print("headers of the result: {}".format((res.headers)))
        assert(60000 < len(res.body) < 80000)
        assert('application/pdf' in res.headers['Content-Type'])
Exemplo n.º 2
0
    def test_dues15_reduction(self):
        """
        test the dues15_reduction functionality
        """
        # have to accept their membersip first
        m1 = C3sMember.get_by_id(1)  # german normal member
        m1.membership_accepted = True
        m2 = C3sMember.get_by_id(2)  # english normal member
        m2.membership_accepted = True

        self.config.add_route('make_dues15_invoice_no_pdf', '/')
        self.config.add_route('make_dues15_reversal_invoice_pdf', '/')
        self.config.add_route('detail', '/detail/')
        self.config.add_route('error_page', '/error_page')
        self.config.add_route('toolbox', '/toolbox')
        req = testing.DummyRequest()
        req.referrer = 'toolbox'
        from c3smembership.views.membership_dues import send_dues15_invoice_batch
        # send out invoices. this is a prerequisite for reductions
        res = send_dues15_invoice_batch(req)
        res
        """
        test reduction of dues
        """
        # pre-check
        self.assertFalse(m1.dues15_reduced)  # not reduced yet!
        _m1_amount_reduced = m1.dues15_amount_reduced  # is Decimal('0')
        _number_of_invoices_before_reduction = len(Dues15Invoice.get_all())
        # print("_number_of_invoices_before_reduction: {}".format(
        #    _number_of_invoices_before_reduction))
        # we have 2 invoices as of now
        self.assertEqual(len(Dues15Invoice.get_all()), 2)
        # import the function under test
        from c3smembership.views.membership_dues import dues15_reduction

        #############################################################
        # try to reduce to the given calculated amount (edge case coverage)
        # this will not work, produce no new invoices
        req_reduce = testing.DummyRequest(  # prepare request
            post={
                'confirmed': 'yes',
                'submit': True,
                'amount': 50,
            }, )
        req_reduce.matchdict['member_id'] = 1  # do it for member with id 1

        res_reduce = dues15_reduction(req_reduce)  # call reduce on her

        self.assertEqual(len(Dues15Invoice.get_all()), 2)  # no new invoice

        #############################################################
        # try to reduce above the given calculated amount
        # this will not work, produce no new invoices
        req_reduce = testing.DummyRequest(  # prepare request
            post={
                'confirmed': 'yes',
                'submit': True,
                'amount': 500,
            }, )
        req_reduce.matchdict['member_id'] = 1  # do it for member with id 1

        res_reduce = dues15_reduction(req_reduce)  # call reduce on her

        self.assertEqual(len(Dues15Invoice.get_all()), 2)  # no new invoice

        #############################################################
        # valid reduction but without confirmation
        req_reduce = testing.DummyRequest(post={
            'confirmed': 'no',
            'submit': True,
            'amount': 42,
        }, )
        req_reduce.matchdict['member_id'] = 1
        res_reduce = dues15_reduction(req_reduce)
        self.assertEqual(len(Dues15Invoice.get_all()), 2)  # no new invoice

        #############################################################
        # valid reduction
        req_reduce = testing.DummyRequest(post={
            'confirmed': 'yes',
            'submit': True,
            'amount': 42,
        }, )
        req_reduce.matchdict['member_id'] = 1
        res_reduce = dues15_reduction(req_reduce)

        _number_of_invoices_after_reduction = len(Dues15Invoice.get_all())

        assert (  # two new invoices must have been issued
            (_number_of_invoices_before_reduction +
             2) == _number_of_invoices_after_reduction)
        assert (_number_of_invoices_after_reduction == 4)
        assert ('detail' in res_reduce.headers['Location'])  # 302 to detail p.
        assert (_m1_amount_reduced != m1.dues15_amount_reduced)  # changed!
        assert (m1.dues15_amount_reduced == 42)  # changed to 42!

        # check the invoice created
        _rev_inv = Dues15Invoice.get_by_invoice_no(
            _number_of_invoices_before_reduction + 1)
        _new_inv = Dues15Invoice.get_by_invoice_no(
            _number_of_invoices_before_reduction + 2)
        # print(_rev_inv.invoice_amount)
        # print(type(_rev_inv.invoice_amount))
        assert (_rev_inv.invoice_amount == D('-50'))
        assert (_new_inv.invoice_amount == D('42'))

        # we have 4 invoices as of now
        self.assertEqual(len(Dues15Invoice.get_all()), 4)

        #############################################################
        # now try to raise above the previous reduction
        req_reduce = testing.DummyRequest(post={
            'confirmed': 'yes',
            'submit': True,
            'amount': 50,
        }, )
        req_reduce.matchdict['member_id'] = 1
        res_reduce = dues15_reduction(req_reduce)

        _number_of_invoices_after_reduction = len(Dues15Invoice.get_all())

        # no new invoices were created, we still have 4 invoices
        self.assertEqual(len(Dues15Invoice.get_all()), 4)

        #############################################################
        # try to reduce to the same amount again (edge case coverage)
        req_reduce = testing.DummyRequest(
            post={
                'confirmed': 'yes',
                'submit': True,
                'amount': 42,
                # lots of values missing
            }, )
        req_reduce.matchdict['member_id'] = 1
        res_reduce = dues15_reduction(req_reduce)
        #############################################################
        # try to reduce to zero (edge case coverage)
        # print("------------- reduction to zero ahead!!!")
        req_reduce = testing.DummyRequest(
            post={
                'confirmed': 'yes',
                'submit': True,
                'amount': 0,
                # lots of values missing
            }, )
        req_reduce.matchdict['member_id'] = 1
        res_reduce = dues15_reduction(req_reduce)

        req_reduce = testing.DummyRequest(
            post={
                'confirmed': 'yes',
                'submit': True,
                'amount': 0,
                # lots of values missing
            }, )
        req_reduce.matchdict['member_id'] = 2
        res_reduce = dues15_reduction(req_reduce)
        #############################################################
        # try to reduce to zero with english member (edge case coverage)
        # how to do this if you already reduced to zero? reduce to more first!
        req_reduce = testing.DummyRequest(
            post={
                'confirmed': 'yes',
                'submit': True,
                'amount': 1,
                # lots of values missing
            }, )
        req_reduce.matchdict['member_id'] = 1
        res_reduce = dues15_reduction(req_reduce)
        m1.locale = u'en'
        req_reduce = testing.DummyRequest(
            post={
                'confirmed': 'yes',
                'submit': True,
                'amount': 0,
                # lots of values missing
            }, )
        req_reduce.matchdict['member_id'] = 1
        res_reduce = dues15_reduction(req_reduce)
        #############################################################
        """
        test reversal invoice PDF generation
        """

        from c3smembership.views.membership_dues import (
            make_dues15_reversal_invoice_pdf)
        req2 = testing.DummyRequest()

        # wrong token: must fail!
        req2.matchdict = {
            'email': m1.email,
            'code': m1.dues15_token + 'false!!!',  # must fail
            'no': u'0006',
        }
        res = make_dues15_reversal_invoice_pdf(req2)
        assert ('application/pdf' not in res.headers['Content-Type'])  # no PDF
        assert ('error_page' in res.headers['Location'])  # but error

        # wrong invoice number: must fail!
        req2.matchdict = {
            'email': m1.email,
            'code': m1.dues15_token,
            'no': u'1234',  # must fail
        }
        res = make_dues15_reversal_invoice_pdf(req2)
        assert ('application/pdf' not in res.headers['Content-Type'])  # no PDF
        assert ('error_page' in res.headers['Location'])  # but error

        # wrong invoice token: must fail!
        i2 = Dues15Invoice.get_by_invoice_no('2')
        i2.token = u'not_matching'
        req2.matchdict = {
            'email': m2.email,
            'code': m2.dues15_token,
            'no': u'2',  # must fail
        }
        res = make_dues15_reversal_invoice_pdf(req2)
        assert ('application/pdf' not in res.headers['Content-Type'])  # no PDF
        assert ('error_page' in res.headers['Location'])  # but error

        ######################################################################
        # wrong invoice type (not a reversal): must fail! (edge case coverage)
        assert (not i2.is_reversal)  # i2 is not a reversal
        i2.token = m2.dues15_token  # we give it a valid token
        req2.matchdict = {
            'email': m2.email,
            'code': m2.dues15_token,
            'no': u'0002',
        }
        res = make_dues15_reversal_invoice_pdf(req2)
        assert ('application/pdf' not in res.headers['Content-Type'])  # no PDF
        assert ('error_page' in res.headers['Location'])  # but error
        ######################################################################

        # retry with valid token:
        req2.matchdict = {
            'email': m1.email,
            'code': m1.dues15_token,
            'no': u'0003',
        }
        res = make_dues15_reversal_invoice_pdf(req2)
        # print("length of the result: {}".format(len(res.body)))
        # print("headers of the result: {}".format((res.headers)))
        assert (60000 < len(res.body) < 80000)
        assert ('application/pdf' in res.headers['Content-Type'])
Exemplo n.º 3
0
    def test_send_dues15_invoice_email_via_BATCH(self):
        """
        test the send_dues15_invoice_batch function
        for batch processing
        """
        # from pyramid_mailer import get_mailer
        from c3smembership.views.membership_dues import send_dues15_invoice_batch
        self.config.add_route('make_dues15_invoice_no_pdf', '/')
        self.config.add_route('make_dues15_reversal_invoice_pdf', '/')
        self.config.add_route('detail', '/detail/')
        self.config.add_route('error_page', '/error_page')
        self.config.add_route('toolbox', '/toolbox')

        # have to accept their membersip first
        m1 = C3sMember.get_by_id(1)  # german normal member
        m1.membership_accepted = True
        m2 = C3sMember.get_by_id(2)  # english normal member
        m2.membership_accepted = True
        m3 = C3sMember.get_by_id(3)  # german investing member
        m3.membership_accepted = True
        m4 = C3sMember.get_by_id(4)  # english investing member
        m4.membership_accepted = True
        m5 = C3sMember.get_by_id(5)  # german investing member
        m5.membership_accepted = True
        m5 = C3sMember.get_by_id(6)  # english investing member
        m5.membership_accepted = True

        # check number of invoices: should be 0
        _number_of_invoices_before_batch = len(Dues15Invoice.get_all())
        # print("_number_of_invoices_before_batch: {}".format(
        #    _number_of_invoices_before_batch))
        assert(_number_of_invoices_before_batch == 0)

        req = testing.DummyRequest()
        req.referrer = 'toolbox'
        res = send_dues15_invoice_batch(req)
        # print res

        # check number of invoices: should be 2
        _number_of_invoices_batch = len(Dues15Invoice.get_all())
        # print("number of invoices after batch: {}".format(
        #    _number_of_invoices_batch))
        assert(_number_of_invoices_batch == 2)

        # try to post a number for batch processing
        req_post = testing.DummyRequest(
            post={
                'submit': True,
                'number': 24
                # lots of values missing
            },
        )
        req.referrer = 'toolbox'
        res = send_dues15_invoice_batch(req_post)

        assert(
            'sent out 5 mails (to members with ids [1, 2, 3, 4, 5])' in
            req.session.pop_flash('message_to_staff'))

        # try to batch-send once more:
        # this will respond with a redirect and tell
        # that there are no invitees left
        res2 = send_dues15_invoice_batch(req)
        # print res2
        self.assertEquals(res2.status, '302 Found')
        self.assertEquals(res2.status_code, 302)
        assert(
            'no invoicees left. all done!' in
            req.session.pop_flash('message_to_staff'))

        """
        and now some tests for make_dues15_invoice_no_pdf
        """
        from c3smembership.views.membership_dues import (
            make_dues15_invoice_no_pdf)
        req2 = testing.DummyRequest()

        # wrong token: must fail!
        req2.matchdict = {
            'email': m1.email,
            'code': m1.dues15_token + 'false!!!',  # must fail
            'i': u'0001',
        }

        res = make_dues15_invoice_no_pdf(req2)

        assert('application/pdf' not in res.headers['Content-Type'])  # no PDF
        assert('error_page' in res.headers['Location'])  # but error

        # wrong invoice number: must fail!
        req2.matchdict = {
            'email': m1.email,
            'code': m1.dues15_token,
            'i': u'1234',  # must fail
        }
        res = make_dues15_invoice_no_pdf(req2)
        assert('application/pdf' not in res.headers['Content-Type'])  # no PDF
        assert('error_page' in res.headers['Location'])  # but error

        # wrong invoice token: must fail!
        i2 = Dues15Invoice.get_by_invoice_no(2)
        i2.token = u'not_matching'
        req2.matchdict = {
            'email': m2.email,
            'code': m2.dues15_token,
            'i': u'3',  # must fail
        }
        res = make_dues15_invoice_no_pdf(req2)
        assert('application/pdf' not in res.headers['Content-Type'])  # no PDF
        assert('error_page' in res.headers['Location'])  # but error

        #######################################################################
        # one more edge case:
        # check _inv.token must match code, or else!!!
        # first, set inv_code to something wrong:
        i1 = Dues15Invoice.get_by_invoice_no(1)
        _old_i1_token = i1.token
        i1.token = u'not_right'
        req2.matchdict = {
            'email': m1.email,
            'code': m1.dues15_token,
            'i': u'0001',
        }
        res = make_dues15_invoice_no_pdf(req2)
        assert('application/pdf' not in res.headers['Content-Type'])  # no PDF
        assert('error_page' in res.headers['Location'])  # but error
        # reset it to what was there before
        i1.token = _old_i1_token
        #######################################################################
        # one more edge case:
        # check this invoice is not a reversal, or else no PDF!!!
        # first, set is_reversal to something wrong:
        i1 = Dues15Invoice.get_by_invoice_no(1)
        _old_i1_reversal_status = i1.is_reversal  # False
        i1.is_reversal = True
        req2.matchdict = {
            'email': m1.email,
            'code': m1.dues15_token,
            'i': u'0001',
        }
        res = make_dues15_invoice_no_pdf(req2)
        assert('application/pdf' not in res.headers['Content-Type'])  # no PDF
        assert('error_page' in res.headers['Location'])  # but error
        # reset it to what was there before
        i1.is_reversal = _old_i1_reversal_status
        #######################################################################

        # retry with valid token:
        req2.matchdict = {
            'email': m1.email,
            'code': m1.dues15_token,
            'i': u'0001',
        }
        res = make_dues15_invoice_no_pdf(req2)
        # m1.
        # print("length of the result: {}".format(len(res.body)))
        # print("headers of the result: {}".format((res.headers)))
        assert(60000 < len(res.body) < 80000)
        assert('application/pdf' in res.headers['Content-Type'])

        """
        test dues listing
        """
        from c3smembership.views.membership_dues import dues15_listing
        req_list = testing.DummyRequest()
        resp_list = dues15_listing(req_list)
        # print resp_list
        # {'count': 5,
        #   'invoices': [
        #       <c3smembership.models.Dues15Invoice object at 0x7f95df761a50>,
        #       <c3smembership.models.Dues15Invoice object at 0x7f95df761690>,
        #       <c3smembership.models.Dues15Invoice object at 0x7f95df815a50>,
        #       <c3smembership.models.Dues15Invoice object at 0x7f95df761c90>,
        #       <c3smembership.models.Dues15Invoice object at 0x7f95df761c10>],
        #   '_today': datetime.date(2015, 9, 1)}
        assert(resp_list['count'] == 2)
Exemplo n.º 4
0
    def test_send_dues15_invoice_email_via_BATCH(self):
        """
        test the send_dues15_invoice_batch function
        for batch processing
        """
        # from pyramid_mailer import get_mailer
        from c3smembership.views.membership_dues import send_dues15_invoice_batch
        self.config.add_route('make_dues15_invoice_no_pdf', '/')
        self.config.add_route('make_dues15_reversal_invoice_pdf', '/')
        self.config.add_route('detail', '/detail/')
        self.config.add_route('error_page', '/error_page')
        self.config.add_route('toolbox', '/toolbox')

        # have to accept their membersip first
        m1 = C3sMember.get_by_id(1)  # german normal member
        m1.membership_accepted = True
        m2 = C3sMember.get_by_id(2)  # english normal member
        m2.membership_accepted = True
        m3 = C3sMember.get_by_id(3)  # german investing member
        m3.membership_accepted = True
        m4 = C3sMember.get_by_id(4)  # english investing member
        m4.membership_accepted = True
        m5 = C3sMember.get_by_id(5)  # german investing member
        m5.membership_accepted = True
        m5 = C3sMember.get_by_id(6)  # english investing member
        m5.membership_accepted = True

        # check number of invoices: should be 0
        _number_of_invoices_before_batch = len(Dues15Invoice.get_all())
        # print("_number_of_invoices_before_batch: {}".format(
        #    _number_of_invoices_before_batch))
        assert (_number_of_invoices_before_batch == 0)

        req = testing.DummyRequest()
        req.referrer = 'toolbox'
        res = send_dues15_invoice_batch(req)
        # print res

        # check number of invoices: should be 2
        _number_of_invoices_batch = len(Dues15Invoice.get_all())
        # print("number of invoices after batch: {}".format(
        #    _number_of_invoices_batch))
        assert (_number_of_invoices_batch == 2)

        # try to post a number for batch processing
        req_post = testing.DummyRequest(
            post={
                'submit': True,
                'number': 24
                # lots of values missing
            }, )
        req.referrer = 'toolbox'
        res = send_dues15_invoice_batch(req_post)

        assert ('sent out 5 mails (to members with ids [1, 2, 3, 4, 5])'
                in req.session.pop_flash('message_to_staff'))

        # try to batch-send once more:
        # this will respond with a redirect and tell
        # that there are no invitees left
        res2 = send_dues15_invoice_batch(req)
        # print res2
        self.assertEquals(res2.status, '302 Found')
        self.assertEquals(res2.status_code, 302)
        assert ('no invoicees left. all done!'
                in req.session.pop_flash('message_to_staff'))
        """
        and now some tests for make_dues15_invoice_no_pdf
        """
        from c3smembership.views.membership_dues import (
            make_dues15_invoice_no_pdf)
        req2 = testing.DummyRequest()

        # wrong token: must fail!
        req2.matchdict = {
            'email': m1.email,
            'code': m1.dues15_token + 'false!!!',  # must fail
            'i': u'0001',
        }

        res = make_dues15_invoice_no_pdf(req2)

        assert ('application/pdf' not in res.headers['Content-Type'])  # no PDF
        assert ('error_page' in res.headers['Location'])  # but error

        # wrong invoice number: must fail!
        req2.matchdict = {
            'email': m1.email,
            'code': m1.dues15_token,
            'i': u'1234',  # must fail
        }
        res = make_dues15_invoice_no_pdf(req2)
        assert ('application/pdf' not in res.headers['Content-Type'])  # no PDF
        assert ('error_page' in res.headers['Location'])  # but error

        # wrong invoice token: must fail!
        i2 = Dues15Invoice.get_by_invoice_no(2)
        i2.token = u'not_matching'
        req2.matchdict = {
            'email': m2.email,
            'code': m2.dues15_token,
            'i': u'3',  # must fail
        }
        res = make_dues15_invoice_no_pdf(req2)
        assert ('application/pdf' not in res.headers['Content-Type'])  # no PDF
        assert ('error_page' in res.headers['Location'])  # but error

        #######################################################################
        # one more edge case:
        # check _inv.token must match code, or else!!!
        # first, set inv_code to something wrong:
        i1 = Dues15Invoice.get_by_invoice_no(1)
        _old_i1_token = i1.token
        i1.token = u'not_right'
        req2.matchdict = {
            'email': m1.email,
            'code': m1.dues15_token,
            'i': u'0001',
        }
        res = make_dues15_invoice_no_pdf(req2)
        assert ('application/pdf' not in res.headers['Content-Type'])  # no PDF
        assert ('error_page' in res.headers['Location'])  # but error
        # reset it to what was there before
        i1.token = _old_i1_token
        #######################################################################
        # one more edge case:
        # check this invoice is not a reversal, or else no PDF!!!
        # first, set is_reversal to something wrong:
        i1 = Dues15Invoice.get_by_invoice_no(1)
        _old_i1_reversal_status = i1.is_reversal  # False
        i1.is_reversal = True
        req2.matchdict = {
            'email': m1.email,
            'code': m1.dues15_token,
            'i': u'0001',
        }
        res = make_dues15_invoice_no_pdf(req2)
        assert ('application/pdf' not in res.headers['Content-Type'])  # no PDF
        assert ('error_page' in res.headers['Location'])  # but error
        # reset it to what was there before
        i1.is_reversal = _old_i1_reversal_status
        #######################################################################

        # retry with valid token:
        req2.matchdict = {
            'email': m1.email,
            'code': m1.dues15_token,
            'i': u'0001',
        }
        res = make_dues15_invoice_no_pdf(req2)
        # m1.
        # print("length of the result: {}".format(len(res.body)))
        # print("headers of the result: {}".format((res.headers)))
        assert (60000 < len(res.body) < 80000)
        assert ('application/pdf' in res.headers['Content-Type'])
        """
        test dues listing
        """
        from c3smembership.views.membership_dues import dues15_listing
        req_list = testing.DummyRequest()
        resp_list = dues15_listing(req_list)
        # print resp_list
        # {'count': 5,
        #   'invoices': [
        #       <c3smembership.models.Dues15Invoice object at 0x7f95df761a50>,
        #       <c3smembership.models.Dues15Invoice object at 0x7f95df761690>,
        #       <c3smembership.models.Dues15Invoice object at 0x7f95df815a50>,
        #       <c3smembership.models.Dues15Invoice object at 0x7f95df761c90>,
        #       <c3smembership.models.Dues15Invoice object at 0x7f95df761c10>],
        #   '_today': datetime.date(2015, 9, 1)}
        assert (resp_list['count'] == 2)