Exemple #1
0
class TestCreateTransaction(FinanceTestCase):
    def setUp(self):
        super(TestCreateTransaction, self).setUp()
        self.url = reverse("finance.createtransaction")

        self.order = OrderFactory(user=self.user, finalized=True, paid=False)

        s = self.client.session
        s["order_to_pay"] = self.order.id
        s.save()

    def test_that_transaction_is_created(self):
        self.client.post(self.url, {"bank": "EXAMPLE_BANK"})
        self.mollie_client.return_value.payments.create.assert_called_once_with(
            {
                "description": "VOKO Utrecht %d" % self.order.id,
                "webhookUrl": settings.BASE_URL + reverse("finance.callback"),
                "amount": float(self.order.total_price_to_pay_with_balances_taken_into_account()),
                "redirectUrl": settings.BASE_URL + "/finance/pay/transaction/confirm/?order=%d" % self.order.id,
                "metadata": {"order_id": self.order.id},
                "method": "ideal",
                "issuer": "EXAMPLE_BANK",
            }
        )

    def test_that_payment_object_is_created(self):
        assert Payment.objects.count() == 0

        self.client.post(self.url, {"bank": "EXAMPLE_BANK"})
        payment = Payment.objects.get()

        self.assertEqual(payment.amount, self.order.total_price_to_pay_with_balances_taken_into_account())
        self.assertEqual(payment.order, self.order)
        self.assertEqual(payment.mollie_id, "transaction_id")
        self.assertEqual(payment.balance, None)

    def test_that_user_is_redirected_to_bank_url(self):
        ret = self.client.post(self.url, {"bank": "EXAMPLE_BANK"})
        self.assertEqual(ret.status_code, 302)
        self.assertEqual(ret.url, "http://bank.url")

    def test_error_when_user_doesnt_own_order(self):
        s = self.client.session
        s["order_to_pay"] = OrderFactory().id
        s.save()

        with self.assertRaises(AssertionError):
            self.client.post(self.url, {"bank": "EXAMPLE_BANK"})

    def test_error_when_order_not_finalized(self):
        self.order.finalized = False
        self.order.save()

        with self.assertRaises(AssertionError):
            self.client.post(self.url, {"bank": "EXAMPLE_BANK"})

    def test_redirect_on_invalid_form(self):
        ret = self.client.post(self.url, {"bank": "foo"})
        self.assertRedirects(ret, reverse("finance.choosebank"))

    def test_redirect_when_order_round_is_closed(self):
        month_ago = datetime.now(tz=UTC) - timedelta(days=30)
        order_round = OrderRoundFactory(closed_for_orders=month_ago)
        assert order_round.is_open is False
        self.order.order_round = order_round
        self.order.save()

        ret = self.client.post(self.url, {"bank": "EXAMPLE_BANK"})
        self.assertRedirects(ret, reverse("finish_order", args=(self.order.id,)), fetch_redirect_response=False)
Exemple #2
0
class TestConfirmTransaction(FinanceTestCase):
    def setUp(self):
        super(TestConfirmTransaction, self).setUp()
        self.url = reverse("finance.confirmtransaction")

        self.order = OrderFactory(user=self.user, finalized=True, paid=False)

        self.payment = PaymentFactory(order=self.order)
        self.client.login()

    def test_required_get_parameters_bad(self):
        ret = self.client.get(self.url, {})
        self.assertEqual(ret.status_code, 404)

    def test_required_get_parameters_good(self):
        ret = self.client.get(self.url, {"order": self.order.id})
        self.assertEqual(ret.status_code, 200)

    def test_mollie_payment_is_obtained(self):
        self.client.get(self.url, {"order": self.order.id})
        self.mollie_client.return_value.payments.get.assert_called_once_with(self.payment.mollie_id)

    def test_ispaid_is_called_on_mollie_payment(self):
        self.client.get(self.url, {"order": self.order.id})
        self.mollie_client.return_value.payments.get.return_value.isPaid.assert_called_once_with()

    def test_context_when_payment_has_failed(self):
        self.mollie_client.return_value.payments.get.return_value.isPaid.return_value = False
        ret = self.client.get(self.url, {"order": self.order.id})
        self.assertEqual(ret.context[0]["payment_succeeded"], False)

    def test_context_when_payment_has_succeeded(self):
        self.mollie_client.return_value.payments.get.return_value.isPaid.return_value = True
        ret = self.client.get(self.url, {"order": self.order.id})
        self.assertEqual(ret.context[0]["payment_succeeded"], True)

    def test_payment_object_is_updated_on_success(self):
        self.assertFalse(self.payment.succeeded)

        self.mollie_client.return_value.payments.get.return_value.isPaid.return_value = True
        self.client.get(self.url, {"order": self.order.id})

        # get new object reference
        payment = Payment.objects.get(id=self.payment.id)
        self.assertTrue(payment.succeeded)

    def test_payment_object_is_not_updated_on_failure(self):
        self.assertFalse(self.payment.succeeded)

        self.mollie_client.return_value.payments.get.return_value.isPaid.return_value = False
        self.client.get(self.url, {"order": self.order.id})

        # get new object reference
        payment = Payment.objects.get(id=self.payment.id)
        self.assertFalse(payment.succeeded)

    def test_payment_and_order_status_after_successful_payment(self):
        self.mollie_client.return_value.payments.get.return_value.isPaid.return_value = True
        self.client.get(self.url, {"order": self.order.id})

        payment = Payment.objects.get()
        self.assertTrue(payment.succeeded)
        self.assertTrue(payment.order.paid)
        self.mock_create_credit.assert_called_once_with()

        debit = Balance.objects.get()
        self.assertEqual(debit.user, payment.order.user)
        self.assertEqual(debit.type, "DR")
        self.assertEqual(debit.amount, payment.order.total_price)
        self.assertEqual(
            debit.notes, "Debit van %s voor bestelling #%s" % (payment.order.total_price, payment.order.id)
        )
        self.mock_mail_confirmation.assert_called_once_with()

    def test_that_order_id_is_removed_from_session_on_successful_payment(self):
        self.mollie_client.return_value.payments.get.return_value.isPaid.return_value = True
        self.client.get(self.url, {"order": self.order.id})

        s = self.client.session
        self.assertNotIn("order_to_pay", s)

    def test_nothing_is_changed_when_payment_already_confirmed(self):
        self.order.paid = True
        self.order.save()
        self.client.get(self.url, {"order": self.order.id})

        ret = self.client.get(self.url, {"order": self.order.id})
        self.assertEqual(ret.context[0]["payment_succeeded"], True)

        self.assertFalse(self.mollie_client.return_value.payments.get.return_value.isPaid.called)

        self.assertFalse(self.mock_create_credit.called)
        self.assertFalse(self.mock_mail_confirmation.called)
Exemple #3
0
class TestPaymentWebhook(FinanceTestCase):
    def setUp(self):
        super(TestPaymentWebhook, self).setUp()

        self.order = OrderFactory(user=self.user, finalized=True, paid=False)
        self.payment = PaymentFactory(order=self.order)

        s = self.client.session
        s["order_to_pay"] = self.order.id
        s.save()

        self.url = reverse("finance.callback")

    def test_required_post_parameters_bad(self):
        ret = self.client.post(self.url, {})
        self.assertEqual(ret.status_code, 404)

    def test_required_post_parameters_good(self):
        ret = self.client.post(self.url, {"id": self.payment.mollie_id})
        self.assertEqual(ret.status_code, 200)

    def test_unsuccessful_payment(self):
        self.mollie_client.return_value.payments.get.return_value.isPaid.return_value = False
        ret = self.client.post(self.url, {"id": self.payment.mollie_id})

        payment = Payment.objects.get(id=self.payment.id)
        self.assertFalse(payment.succeeded)
        self.assertFalse(self.mock_create_credit.called)
        self.assertFalse(payment.order.paid)
        self.assertFalse(payment.order.debit)
        self.assertFalse(self.mock_mail_confirmation.called)
        # self.assertFalse(self.mock_complete_after_payment.called)

        self.assertEqual(ret.status_code, 200)
        self.assertEqual(ret.content, "")

    def test_successful_payment(self):
        self.mollie_client.return_value.payments.get.return_value.isPaid.return_value = True
        ret = self.client.post(self.url, {"id": self.payment.mollie_id})

        payment = Payment.objects.get(id=self.payment.id)
        self.assertTrue(payment.succeeded)
        self.assertTrue(self.mock_create_credit.called)
        self.assertTrue(payment.order.paid)
        self.assertTrue(payment.order.debit)
        self.assertTrue(self.mock_mail_confirmation.called)
        # self.mock_complete_after_payment.assert_called_once_with()

        self.assertEqual(ret.status_code, 200)
        self.assertEqual(ret.content, "")

    def test_order_is_completed_when_order_paid_is_false(self):
        assert self.order.paid is False
        self.mollie_client.return_value.payments.get.return_value.isPaid.return_value = True
        ret = self.client.post(self.url, {"id": self.payment.mollie_id})

        # self.mock_complete_after_payment.assert_called_once_with()

    def test_order_is_not_completed_when_round_is_closed_and_notification_is_sent(self):
        month_ago = datetime.now(tz=UTC) - timedelta(days=30)
        order_round = OrderRoundFactory(closed_for_orders=month_ago)
        assert order_round.is_open is False
        self.order.order_round = order_round
        self.order.save()

        assert self.order.paid is False

        self.mollie_client.return_value.payments.get.return_value.isPaid.return_value = True
        ret = self.client.post(self.url, {"id": self.payment.mollie_id})

        payment = Payment.objects.get()
        self.assertFalse(payment.order.paid)
        self.mock_create_credit.assert_called_once_with()
        # self.assertFalse(self.mock_complete_after_payment.called)

        self.mock_failure_notification.assert_called_once_with()
Exemple #4
0
class TestProductsView(VokoTestCase):
    def setUp(self):
        self.round = OrderRoundFactory()
        self.url = reverse('view_products')
        self.login()
        self.order = OrderFactory(paid=False, finalized=False, user=self.user, order_round=self.round)

    def test_login_required(self):
        self.logout()
        ret = self.client.get(self.url)
        self.assertEqual(ret.status_code, 302)

    def test_product_round_override(self):
        round1 = self.round
        round2 = OrderRoundFactory()
        products1 = ProductFactory.create_batch(50, order_round=round1)
        products2 = ProductFactory.create_batch(50, order_round=round2)

        ret = self.client.get(self.url)
        self.assertItemsEqual(ret.context['object_list'], products1)

        ret = self.client.get(self.url + "?round=%d" % round2.id)
        self.assertItemsEqual(ret.context['object_list'], products2)

    def test_context_contains_current_order_round(self):
        current = self.round
        other_round = OrderRoundFactory()

        ret = self.client.get(self.url)
        self.assertEqual(ret.context['current_order_round'], current)

        ret = self.client.get(self.url + "?round=%d" % other_round.id)
        self.assertEqual(ret.context['current_order_round'], other_round)

    def test_context_contains_products_ordered_by_name(self):
        ProductFactory.create_batch(50, order_round=self.round)
        ret = self.client.get(self.url)
        self.assertItemsEqual(ret.context['view'].products(), Product.objects.all().order_by('name'))

    def test_attribute_is_added_to_products_for_which_an_orderproduct_exists(self):
        order = OrderFactory(order_round=self.round, user=self.user)
        product = ProductFactory(order_round=self.round)

        odp1 = OrderProductFactory(order=order, product=product)

        ret = self.client.get(self.url)
        self.assertEqual(list(ret.context['view'].products())[0].ordered_amount, odp1.amount)

    def test_stock_products_without_stock_are_excluded(self):
        order = OrderFactory(order_round=self.round, user=self.user)

        product = ProductFactory(order_round=self.round)
        sproduct = ProductFactory(order_round=None)

        odp1 = OrderProductFactory(order=order, product=product)
        odp2 = OrderProductFactory(order=order, product=sproduct)

        ret = self.client.get(self.url)
        self.assertNotIn(sproduct, list(ret.context['view'].products()))
        self.assertIn(product, list(ret.context['view'].products()))

    def test_context_contains_categories_alphabetically_sorted(self):
        cat1 = ProductCategoryFactory(name="Zeep")
        cat2 = ProductCategoryFactory(name="Kaas")
        cat3 = ProductCategoryFactory(name="Appels")

        ret = self.client.get(self.url)
        self.assertEqual(ret.context['view'].categories()[0], cat3)
        self.assertEqual(ret.context['view'].categories()[1], cat2)
        self.assertEqual(ret.context['view'].categories()[2], cat1)

    def test_context_contains_supplier_objects(self):
        suppliers = SupplierFactory.create_batch(10)
        ret = self.client.get(self.url)
        self.assertItemsEqual(ret.context['view'].suppliers(), suppliers)

    def test_redirect_to_payment_page_when_current_order_is_finalized(self):
        self.patch("finance.views.Mollie")

        OrderFactory(order_round=self.round, user=self.user, finalized=True)
        ret = self.client.get(self.url, follow=True)
        self.assertRedirects(ret, reverse('finance.choosebank'), fetch_redirect_response=True)
        self.assertMsgInResponse(ret, "Je bent doorgestuurd naar de betaalpagina "
                                      "omdat je bestelling nog niet is betaald!")

    def test_submit_without_data(self):
        ret = self.client.post(self.url)
        self.assertFalse(OrderProduct.objects.exists())
        self.assertRedirects(ret, reverse("finish_order", args=(self.order.id,)))

    def test_submit_without_data_2(self):
        OrderProductFactory.create_batch(10, product__order_round=self.round, order__user=self.user)
        ret = self.client.post(self.url)
        self.assertEqual(len(OrderProduct.objects.all()), 10)

        self.assertRedirects(ret, reverse("finish_order", args=(self.order.id,)))

    def test_order_one_product(self):
        self.assertFalse(OrderProduct.objects.exists())

        product = ProductFactory(order_round=self.round)
        ret = self.client.post(self.url, {
            "order-product-%d" % product.id: 3
        })

        odp = OrderProduct.objects.get()
        self.assertEqual(odp.product, product)
        self.assertEqual(odp.amount, 3)
        self.assertEqual(odp.order.order_round, self.round)
        self.assertEqual(odp.total_retail_price, product.retail_price * 3)
        self.assertEqual(odp.base_price, product.base_price)
        self.assertEqual(odp.retail_price, product.retail_price)

        self.assertRedirects(ret, reverse("finish_order", args=(self.order.id,)))

    def test_delete_all_products_of_user(self):
        user_odps = OrderProductFactory.create_batch(10, product__order_round=self.round, order=self.order)
        other_odps = OrderProductFactory.create_batch(10, product__order_round=self.round, order=self.order)

        data = {}
        for odp in user_odps:
            data["order-product-%d" % odp.product.id] = 0

        ret = self.client.post(self.url, data)
        self.assertEqual(len(OrderProduct.objects.all()), 10)
        self.assertItemsEqual(OrderProduct.objects.all(), other_odps)

        self.assertRedirects(ret, reverse("finish_order", args=(self.order.id,)))

    def test_delete_some_products(self):
        user_odps = OrderProductFactory.create_batch(10, product__order_round=self.round, order=self.order)
        other_odps = OrderProductFactory.create_batch(10, product__order_round=self.round, order=self.order)

        data = {}
        for odp in user_odps[:5]:
            data["order-product-%d" % odp.product.id] = ""

        ret = self.client.post(self.url, data)
        self.assertEqual(len(OrderProduct.objects.all()), 15)
        self.assertItemsEqual(OrderProduct.objects.all(), other_odps + user_odps[5:])

        self.assertRedirects(ret, reverse("finish_order", args=(self.order.id,)))

    def test_change_amounts(self):
        user_odps = OrderProductFactory.create_batch(10, product__order_round=self.round, order=self.order,
                                                     amount=5)

        data = {}
        for odp in user_odps:
            data["order-product-%d" % odp.product.id] = "3"
        ret = self.client.post(self.url, data)

        for odp in OrderProduct.objects.all():
            self.assertEqual(odp.amount, 3)

        self.assertRedirects(ret, reverse("finish_order", args=(self.order.id,)))

    def test_other_keys_in_post_data_are_ignored(self):
        odps = OrderProductFactory.create_batch(10, product__order_round=self.round, order=self.order)
        ret = self.client.post(self.url, {"order_product_999": 12,
                                          "foo": "bar"})
        self.assertItemsEqual(OrderProduct.objects.all(), odps)
        self.assertRedirects(ret, reverse("finish_order", args=(self.order.id,)))

    def test_tamper_with_ids_1(self):
        ret = self.client.post(self.url, {"order-product-0": 1}, follow=True)
        self.assertFalse(OrderProduct.objects.exists())
        self.assertRedirects(ret, reverse("view_products"))
        self.assertMsgInResponse(ret, "Er ging iets fout bij het opslaan. "
                                      "Probeer het opnieuw of neem contact met ons op.")

    def test_tamper_with_ids_2(self):
        ret = self.client.post(self.url, {"order-product-x": 1}, follow=True)
        self.assertFalse(OrderProduct.objects.exists())
        self.assertRedirects(ret, reverse("view_products"))
        self.assertMsgInResponse(ret, "Er ging iets fout bij het opslaan. "
                                      "Probeer het opnieuw of neem contact met ons op.")

    def test_order_sold_out_product(self):
        sold_out_odp = OrderProductFactory(product__order_round=self.round, order=self.order,
                                           product__maximum_total_order=1, amount=1)
        self.order.finalized = True
        self.order.paid = True
        self.order.save()
        self.assertFalse(sold_out_odp.product.is_available)

        ret = self.client.post(self.url, {"order-product-%d" % sold_out_odp.product.id : 1}, follow=True)
        self.assertMsgInResponse(ret, "Het product '%s' van %s is uitverkocht!" %
                                 (sold_out_odp.product.name, sold_out_odp.product.supplier.name))

    def test_order_more_than_max(self):
        product = ProductFactory(order_round=self.round, maximum_total_order=1)
        self.assertTrue(product.is_available)

        ret = self.client.post(self.url, {"order-product-%d" % product.id : 2}, follow=True)
        self.assertMsgInResponse(ret,  "Van het product '%s' van %s is nog %s %s beschikbaar!" %
                                 (product.name, product.supplier.name, product.amount_available,
                                  product.unit_of_measurement.lower()))
Exemple #5
0
class TestProductsView(VokoTestCase):
    def setUp(self):
        self.round = OrderRoundFactory()
        self.url = reverse('view_products')
        self.login()
        self.order = OrderFactory(paid=False,
                                  finalized=False,
                                  user=self.user,
                                  order_round=self.round)

    def test_login_required(self):
        self.logout()
        ret = self.client.get(self.url)
        self.assertEqual(ret.status_code, 302)

    def test_product_round_override(self):
        round1 = self.round
        round2 = OrderRoundFactory()
        products1 = ProductFactory.create_batch(50, order_round=round1)
        products2 = ProductFactory.create_batch(50, order_round=round2)

        ret = self.client.get(self.url)
        self.assertCountEqual(ret.context['object_list'], products1)

        ret = self.client.get(self.url + "?round=%d" % round2.id)
        self.assertCountEqual(ret.context['object_list'], products2)

    def test_context_contains_current_order_round(self):
        current = self.round
        other_round = OrderRoundFactory()

        ret = self.client.get(self.url)
        self.assertEqual(ret.context['current_order_round'], current)

        ret = self.client.get(self.url + "?round=%d" % other_round.id)
        self.assertEqual(ret.context['current_order_round'], other_round)

    def test_context_contains_products_ordered_by_name(self):
        ProductFactory.create_batch(50, order_round=self.round)
        ret = self.client.get(self.url)
        self.assertCountEqual(ret.context['view'].products(),
                              Product.objects.all().order_by('name'))

    def test_attribute_is_added_to_products_with_orderproduct(self):
        order = OrderFactory(order_round=self.round, user=self.user)
        product = ProductFactory(order_round=self.round)

        odp1 = OrderProductFactory(order=order, product=product)

        ret = self.client.get(self.url)
        self.assertEqual(
            list(ret.context['view'].products())[0].ordered_amount,
            odp1.amount)

    def test_stock_products_without_stock_are_excluded(self):
        order = OrderFactory(order_round=self.round, user=self.user)

        product = ProductFactory(order_round=self.round)
        sproduct = ProductFactory(order_round=None)

        OrderProductFactory(order=order, product=product)
        OrderProductFactory(order=order, product=sproduct)

        ret = self.client.get(self.url)
        self.assertNotIn(sproduct, list(ret.context['view'].products()))
        self.assertIn(product, list(ret.context['view'].products()))

    def test_context_contains_categories_alphabetically_sorted(self):
        cat1 = ProductCategoryFactory(name="Zeep")
        cat2 = ProductCategoryFactory(name="Kaas")
        cat3 = ProductCategoryFactory(name="Appels")

        ret = self.client.get(self.url)
        self.assertEqual(ret.context['view'].categories()[0], cat3)
        self.assertEqual(ret.context['view'].categories()[1], cat2)
        self.assertEqual(ret.context['view'].categories()[2], cat1)

    @skip(
        "TODO: Update test, only suppliers for products in round are now returned"
    )  # noqa
    def test_context_contains_supplier_objects(self):
        suppliers = SupplierFactory.create_batch(10)
        ret = self.client.get(self.url)
        self.assertCountEqual(ret.context['view'].suppliers(), suppliers)

    def test_redirect_to_payment_page_when_current_order_is_finalized(self):
        self.patch("finance.views.Mollie")

        OrderFactory(order_round=self.round, user=self.user, finalized=True)
        ret = self.client.get(self.url, follow=True)
        self.assertRedirects(ret,
                             reverse('finance.choosebank'),
                             fetch_redirect_response=True)
        self.assertMsgInResponse(
            ret, "Je bent doorgestuurd naar de betaalpagina "
            "omdat je bestelling nog niet is betaald!")

    def test_submit_without_data(self):
        ret = self.client.post(self.url)
        self.assertFalse(OrderProduct.objects.exists())
        self.assertRedirects(ret,
                             reverse("finish_order", args=(self.order.id, )))

    def test_submit_without_data_2(self):
        OrderProductFactory.create_batch(10,
                                         product__order_round=self.round,
                                         order__user=self.user)
        ret = self.client.post(self.url)
        self.assertEqual(len(OrderProduct.objects.all()), 10)

        self.assertRedirects(ret,
                             reverse("finish_order", args=(self.order.id, )))

    def test_order_one_product(self):
        self.assertFalse(OrderProduct.objects.exists())

        product = ProductFactory(order_round=self.round)
        ret = self.client.post(self.url, {"order-product-%d" % product.id: 3})

        odp = OrderProduct.objects.get()
        self.assertEqual(odp.product, product)
        self.assertEqual(odp.amount, 3)
        self.assertEqual(odp.order.order_round, self.round)
        self.assertEqual(odp.total_retail_price, product.retail_price * 3)
        self.assertEqual(odp.base_price, product.base_price)
        self.assertEqual(odp.retail_price, product.retail_price)

        self.assertRedirects(ret,
                             reverse("finish_order", args=(self.order.id, )))

    def test_delete_all_products_of_user(self):
        user_odps = OrderProductFactory.create_batch(
            10, product__order_round=self.round, order=self.order)
        other_odps = OrderProductFactory.create_batch(
            10, product__order_round=self.round, order=self.order)

        data = {}
        for odp in user_odps:
            data["order-product-%d" % odp.product.id] = 0

        ret = self.client.post(self.url, data)
        self.assertEqual(len(OrderProduct.objects.all()), 10)
        self.assertCountEqual(OrderProduct.objects.all(), other_odps)

        self.assertRedirects(ret,
                             reverse("finish_order", args=(self.order.id, )))

    def test_delete_some_products(self):
        user_odps = OrderProductFactory.create_batch(
            10, product__order_round=self.round, order=self.order)
        other_odps = OrderProductFactory.create_batch(
            10, product__order_round=self.round, order=self.order)

        data = {}
        for odp in user_odps[:5]:
            data["order-product-%d" % odp.product.id] = ""

        ret = self.client.post(self.url, data)
        self.assertEqual(len(OrderProduct.objects.all()), 15)
        self.assertCountEqual(OrderProduct.objects.all(),
                              other_odps + user_odps[5:])

        self.assertRedirects(ret,
                             reverse("finish_order", args=(self.order.id, )))

    def test_change_amounts(self):
        user_odps = OrderProductFactory.create_batch(
            10, product__order_round=self.round, order=self.order, amount=5)

        data = {}
        for odp in user_odps:
            data["order-product-%d" % odp.product.id] = "3"
        ret = self.client.post(self.url, data)

        for odp in OrderProduct.objects.all():
            self.assertEqual(odp.amount, 3)

        self.assertRedirects(ret,
                             reverse("finish_order", args=(self.order.id, )))

    def test_other_keys_in_post_data_are_ignored(self):
        odps = OrderProductFactory.create_batch(
            10, product__order_round=self.round, order=self.order)
        ret = self.client.post(self.url, {
            "order_product_999": 12,
            "foo": "bar"
        })
        self.assertCountEqual(OrderProduct.objects.all(), odps)
        self.assertRedirects(ret,
                             reverse("finish_order", args=(self.order.id, )))

    def test_tamper_with_ids_1(self):
        ret = self.client.post(self.url, {"order-product-0": 1}, follow=True)
        self.assertFalse(OrderProduct.objects.exists())
        self.assertRedirects(ret, reverse("view_products"))
        self.assertMsgInResponse(
            ret, "Er ging iets fout bij het opslaan. "
            "Probeer het opnieuw of neem contact met ons op.")

    def test_tamper_with_ids_2(self):
        ret = self.client.post(self.url, {"order-product-x": 1}, follow=True)
        self.assertFalse(OrderProduct.objects.exists())
        self.assertRedirects(ret, reverse("view_products"))
        self.assertMsgInResponse(
            ret, "Er ging iets fout bij het opslaan. "
            "Probeer het opnieuw of neem contact met ons op.")

    def test_order_sold_out_product(self):
        sold_out_odp = OrderProductFactory(product__order_round=self.round,
                                           order=self.order,
                                           product__maximum_total_order=1,
                                           amount=1)
        self.order.finalized = True
        self.order.paid = True
        self.order.save()
        self.assertFalse(sold_out_odp.product.is_available)

        ret = self.client.post(
            self.url, {"order-product-%d" % sold_out_odp.product.id: 1},
            follow=True)
        self.assertMsgInResponse(
            ret, "Het product '%s' van %s is uitverkocht!" %
            (sold_out_odp.product.name, sold_out_odp.product.supplier.name))

    def test_order_more_than_max(self):
        product = ProductFactory(order_round=self.round, maximum_total_order=1)
        self.assertTrue(product.is_available)

        ret = self.client.post(self.url, {"order-product-%d" % product.id: 2},
                               follow=True)
        self.assertMsgInResponse(
            ret, "Van het product '%s' van %s is nog %s %s beschikbaar!" %
            (product.name, product.supplier.name, product.amount_available,
             product.unit_of_measurement.lower()))
Exemple #6
0
class TestPaymentWebhook(FinanceTestCase):
    def setUp(self):
        super(TestPaymentWebhook, self).setUp()

        self.order = OrderFactory(user=self.user,
                                  finalized=True,
                                  paid=False)
        self.payment = PaymentFactory(order=self.order)

        self.url = reverse('finance.callback')

    def test_required_post_parameters_bad(self):
        ret = self.client.post(self.url, {})
        self.assertEqual(ret.status_code, 404)

    def test_required_post_parameters_good(self):
        ret = self.client.post(self.url, {"id": self.payment.mollie_id})
        self.assertEqual(ret.status_code, 200)

    def test_unsuccessful_payment(self):
        self.mollie_client.return_value.payments.get. \
            return_value.isPaid.return_value = False
        ret = self.client.post(self.url, {"id": self.payment.mollie_id})

        payment = Payment.objects.get(id=self.payment.id)
        self.assertFalse(payment.succeeded)
        self.assertFalse(self.mock_create_credit.called)
        self.assertFalse(payment.order.paid)
        self.assertFalse(payment.order.debit)
        self.assertFalse(self.mock_mail_confirmation.called)
        # self.assertFalse(self.mock_complete_after_payment.called)

        self.assertEqual(ret.status_code, 200)
        self.assertEqual(ret.content, b"")

    def test_successful_payment(self):
        self.mollie_client.return_value.payments.get. \
            return_value.isPaid.return_value = True
        ret = self.client.post(self.url, {"id": self.payment.mollie_id})

        payment = Payment.objects.get(id=self.payment.id)
        self.assertTrue(payment.succeeded)
        self.assertTrue(self.mock_create_credit.called)
        self.assertTrue(payment.order.paid)
        self.assertTrue(payment.order.debit)
        self.assertTrue(self.mock_mail_confirmation.called)
        # self.mock_complete_after_payment.assert_called_once_with()

        self.assertEqual(ret.status_code, 200)
        self.assertEqual(ret.content, b"")

    def test_order_is_completed_when_order_paid_is_false(self):
        assert self.order.paid is False
        self.mollie_client.return_value.payments.get. \
            return_value.isPaid.return_value = True
        self.client.post(self.url, {"id": self.payment.mollie_id})

        # self.mock_complete_after_payment.assert_called_once_with()

    def test_order_is_not_completed_when_round_is_closed_and_notification_is_sent(self):  # noqa
        month_ago = datetime.now(tz=UTC) - timedelta(days=30)
        order_round = OrderRoundFactory(closed_for_orders=month_ago)
        assert order_round.is_open is False
        self.order.order_round = order_round
        self.order.save()

        assert self.order.paid is False

        self.mollie_client.return_value.payments.get. \
            return_value.isPaid.return_value = True
        self.client.post(self.url, {"id": self.payment.mollie_id})

        payment = Payment.objects.get()
        self.assertFalse(payment.order.paid)
        self.mock_create_credit.assert_called_once_with()
        # self.assertFalse(self.mock_complete_after_payment.called)

        self.mock_failure_notification.assert_called_once_with()
Exemple #7
0
class TestConfirmTransaction(FinanceTestCase):
    def setUp(self):
        super(TestConfirmTransaction, self).setUp()
        self.url = reverse('finance.confirmtransaction')

        self.order = OrderFactory(user=self.user,
                                  finalized=True,
                                  paid=False)

        self.payment = PaymentFactory(order=self.order)
        self.client.login()

    def test_required_get_parameters_bad(self):
        ret = self.client.get(self.url, {})
        self.assertEqual(ret.status_code, 404)

    def test_required_get_parameters_good(self):
        ret = self.client.get(self.url, {"order": self.order.id})
        self.assertEqual(ret.status_code, 200)

    def test_mollie_payment_is_obtained(self):
        self.client.get(self.url, {"order": self.order.id})
        self.mollie_client.return_value.payments.get.assert_called_once_with(
            self.payment.mollie_id)

    def test_ispaid_is_called_on_mollie_payment(self):
        self.client.get(self.url, {"order": self.order.id})
        self.mollie_client.return_value.payments.get.\
            return_value.isPaid.assert_called_once_with()

    def test_context_when_payment_has_failed(self):
        self.mollie_client.return_value.payments.get.\
            return_value.isPaid.return_value = False
        ret = self.client.get(self.url, {"order": self.order.id})
        self.assertEqual(ret.context[0]['payment_succeeded'], False)

    def test_context_when_payment_has_succeeded(self):
        self.mollie_client.return_value.payments.get.\
            return_value.isPaid.return_value = True
        ret = self.client.get(self.url, {"order": self.order.id})
        self.assertEqual(ret.context[0]['payment_succeeded'], True)

    def test_payment_object_is_updated_on_success(self):
        self.assertFalse(self.payment.succeeded)

        self.mollie_client.return_value.payments.get. \
            return_value.isPaid.return_value = True
        self.client.get(self.url, {"order": self.order.id})

        # get new object reference
        payment = Payment.objects.get(id=self.payment.id)
        self.assertTrue(payment.succeeded)

    def test_payment_object_is_not_updated_on_failure(self):
        self.assertFalse(self.payment.succeeded)

        self.mollie_client.return_value.payments.get. \
            return_value.isPaid.return_value = False
        self.client.get(self.url, {"order": self.order.id})

        # get new object reference
        payment = Payment.objects.get(id=self.payment.id)
        self.assertFalse(payment.succeeded)

    def test_payment_and_order_status_after_successful_payment(self):
        self.mollie_client.return_value.payments.get. \
            return_value.isPaid.return_value = True
        self.client.get(self.url, {"order": self.order.id})

        payment = Payment.objects.get()
        self.assertTrue(payment.succeeded)
        self.assertTrue(payment.order.paid)
        self.mock_create_credit.assert_called_once_with()

        debit = Balance.objects.get()
        self.assertEqual(debit.user, payment.order.user)
        self.assertEqual(debit.type, 'DR')
        self.assertEqual(debit.amount, payment.order.total_price)
        self.assertEqual(debit.notes, 'Debit van %s voor bestelling #%s' %
                         (payment.order.total_price, payment.order.id))
        self.mock_mail_confirmation.assert_called_once_with()

    def test_nothing_is_changed_when_payment_already_confirmed(self):
        self.order.paid = True
        self.order.save()
        self.client.get(self.url, {"order": self.order.id})

        ret = self.client.get(self.url, {"order": self.order.id})
        self.assertEqual(ret.context[0]['payment_succeeded'], True)

        self.assertFalse(self.mollie_client.return_value.payments.get.
                         return_value.isPaid.called)

        self.assertFalse(self.mock_create_credit.called)
        self.assertFalse(self.mock_mail_confirmation.called)
Exemple #8
0
class TestCreateTransaction(FinanceTestCase):
    def setUp(self):
        super(TestCreateTransaction, self).setUp()
        self.url = reverse('finance.createtransaction')

        self.order = OrderFactory(user=self.user,
                                  finalized=True,
                                  paid=False)

    def test_that_transaction_is_created(self):
        self.client.post(self.url, {'bank': 'EXAMPLE_BANK'})
        self.mollie_client.return_value.payments.create.assert_called_once_with(  # noqa
            {'description': 'VOKO Utrecht %d' % self.order.id,
             'webhookUrl': settings.BASE_URL + reverse('finance.callback'),
             'amount': float(self.order.total_price_to_pay_with_balances_taken_into_account()),  # noqa
             'redirectUrl': (settings.BASE_URL +
                             '/finance/pay/transaction/confirm/?order=%d'
                             % self.order.id),
             'metadata': {'order_id': self.order.id},
             'method': 'ideal',
             'issuer': 'EXAMPLE_BANK'}
        )

    def test_that_payment_object_is_created(self):
        assert Payment.objects.count() == 0

        self.client.post(self.url, {'bank': "EXAMPLE_BANK"})
        payment = Payment.objects.get()

        self.assertEqual(
            payment.amount,
            self.order.total_price_to_pay_with_balances_taken_into_account()
        )
        self.assertEqual(payment.order, self.order)
        self.assertEqual(payment.mollie_id, "transaction_id")
        self.assertEqual(payment.balance, None)

    def test_that_user_is_redirected_to_bank_url(self):
        ret = self.client.post(self.url, {'bank': "EXAMPLE_BANK"})
        self.assertEqual(ret.status_code, 302)
        self.assertEqual(ret.url, "http://bank.url")

    def test_redirect_when_order_not_finalized(self):
        # No order matches, so not found
        self.order.finalized = False
        self.order.save()

        ret = self.client.post(self.url, {'bank': "EXAMPLE_BANK"})
        self.assertRedirects(ret, reverse('view_products'))

    def test_redirect_on_invalid_form(self):
        ret = self.client.post(self.url, {'bank': 'foo'})
        self.assertRedirects(ret, reverse('finance.choosebank'))

    def test_redirect_when_order_round_is_closed(self):
        # No order matches, so not found
        month_ago = datetime.now(tz=UTC) - timedelta(days=30)
        order_round = OrderRoundFactory(closed_for_orders=month_ago)
        assert order_round.is_open is False
        self.order.order_round = order_round
        self.order.save()

        ret = self.client.post(self.url, {'bank': "EXAMPLE_BANK"})
        self.assertRedirects(ret, reverse('view_products'))