from django.contrib.messages import get_messages
from django.test import TestCase
from django.urls import reverse

from oscar.apps.basket import views
from oscar.test import factories
from tests.fixtures import RequestFactory


class TestVoucherAddView(TestCase):
    def test_get(self):
        request = RequestFactory().get('/')

        view = views.VoucherAddView.as_view()
        response = view(request)

        self.assertEqual(response.status_code, 302)

    def _get_voucher_message(self, request):
        return '\n'.join(str(m.message) for m in get_messages(request))

    def test_post_valid(self):
        voucher = factories.VoucherFactory()
        self.assertTrue(voucher.is_active())

        data = {
            'code': voucher.code
        }
        request = RequestFactory().post('/', data=data)
        request.basket.save()

        view = views.VoucherAddView.as_view()
        response = view(request)
        self.assertEqual(response.status_code, 302)

        voucher = voucher.__class__.objects.get(pk=voucher.pk)
        self.assertEqual(voucher.num_basket_additions, 1, msg=self._get_voucher_message(request))

    def test_post_valid_from_set(self):
        voucherset = factories.VoucherSetFactory()
        voucher = voucherset.vouchers.first()

        self.assertTrue(voucher.is_active())

        data = {
            'code': voucher.code
        }
        request = RequestFactory().post('/', data=data)
        request.basket.save()

        view = views.VoucherAddView.as_view()
        response = view(request)
        self.assertEqual(response.status_code, 302)

        voucher = voucher.__class__.objects.get(pk=voucher.pk)
        self.assertEqual(voucher.num_basket_additions, 1, msg=self._get_voucher_message(request))

        self.assertEqual(voucherset.num_basket_additions, 1)


class TestVoucherRemoveView(TestCase):
    def test_post_valid(self):
        voucher = factories.VoucherFactory(num_basket_additions=5)

        data = {
            'code': voucher.code
        }
        request = RequestFactory().post('/', data=data)
        request.basket.save()
        request.basket.vouchers.add(voucher)

        view = views.VoucherRemoveView.as_view()
        response = view(request, pk=voucher.pk)
        self.assertEqual(response.status_code, 302)

        voucher = voucher.__class__.objects.get(pk=voucher.pk)
        self.assertEqual(voucher.num_basket_additions, 4)

    def test_post_with_missing_voucher(self):
        """ If the voucher is missing, verify the view queues a message and redirects. """
        pk = '12345'
        view = views.VoucherRemoveView.as_view()
        request = RequestFactory().post('/')
        request.basket.save()
        response = view(request, pk=pk)

        self.assertEqual(response.status_code, 302)

        actual = list(get_messages(request))[-1].message
        expected = "No voucher found with id '{}'".format(pk)
        self.assertEqual(actual, expected)


class TestBasketSummaryView(TestCase):
    def setUp(self):
        self.url = reverse('basket:summary')
        self.country = factories.CountryFactory()
        self.user = factories.UserFactory()

    def test_default_shipping_address(self):
        user_address = factories.UserAddressFactory(
            country=self.country, user=self.user, is_default_for_shipping=True
        )
        request = RequestFactory().get(self.url, user=self.user)
        view = views.BasketView(request=request)
        self.assertEqual(view.get_default_shipping_address(), user_address)

    def test_default_shipping_address_for_anonymous_user(self):
        request = RequestFactory().get(self.url)
        view = views.BasketView(request=request)
        self.assertIsNone(view.get_default_shipping_address())

@@ -186,44 +186,141 @@
 rom 
-tests.fixtures import RequestFactory
+oscar.test.testcases import WebTestCase%0Afrom tests.fixtures import RequestFactory%0Afrom tests.functional.checkout import CheckoutMixin
 %0A%0A%0Ac
@@ -3866,12 +3866,1115 @@
 _address())%0A
+%0A%0Aclass TestVoucherViews(CheckoutMixin, WebTestCase):%0A    csrf_checks = False%0A%0A    def setUp(self):%0A        self.voucher = factories.create_voucher()%0A        super().setUp()%0A%0A    def test_add_voucher(self):%0A        %22%22%22%0A        Checks that voucher can be added to basket through appropriate view.%0A        %22%22%22%0A        self.add_product_to_basket()%0A%0A        assert self.voucher.basket_set.count() == 0%0A%0A        response = self.post(reverse('basket:vouchers-add'), params=%7B'code': self.voucher.code%7D)%0A        self.assertRedirectsTo(response, 'basket:summary')%0A        assert self.voucher.basket_set.count() == 1%0A%0A    def test_remove_voucher(self):%0A        %22%22%22%0A        Checks that voucher can be removed from basket through appropriate view.%0A        %22%22%22%0A        self.add_product_to_basket()%0A        self.add_voucher_to_basket(voucher=self.voucher)%0A%0A        assert self.voucher.basket_set.count() == 1%0A%0A        response = self.post(reverse('basket:vouchers-remove', kwargs=%7B'pk': self.voucher.id%7D))%0A        self.assertRedirectsTo(response, 'basket:summary')%0A        assert self.voucher.basket_set.count() == 0%0A

Add test to check adding/removing of a voucher