from django.test import TestCase
from mock import MagicMock, patch

from . import BillingAddressStep, ShippingStep
from ..checkout import Checkout, STORAGE_SESSION_KEY
from ..checkout.steps import BaseAddressStep
from ..userprofile.models import Address

NEW_ADDRESS = {
    'first_name': 'Test',
    'last_name': 'Test',
    'street_address_1': 'Test',
    'city': 'Test',
    'postal_code': '987654',
    'country': 'PL'}


class TestBaseAddressStep(TestCase):

    def setUp(self):
        self.request = MagicMock()
        self.request.user.is_authenticated.return_value = False
        self.checkout = MagicMock()
        self.address = Address()

    def test_new_method(self):
        '''
        Test the BaseAddressStep managment form when method is set to 'new'
        and user isn't authenticated.
        '''
        self.request.POST = NEW_ADDRESS
        step = BaseAddressStep(self.checkout, self.request, {}, self.address)
        self.assertTrue(step.forms_are_valid(), 'Forms don\'t validate.')
        self.assertEqual(step.address.first_name, 'Test')


class TestBillingAddressStep(TestCase):

    def setUp(self):
        self.request = MagicMock()
        self.request.user.is_authenticated.return_value = False
        self.checkout = MagicMock()

    def test_address_save_without_address(self):
        self.checkout.billing_address = None
        self.request.POST = NEW_ADDRESS
        storage = {}
        step = BillingAddressStep(self.checkout, self.request, storage)
        self.assertEquals(step.process(), None)
        self.checkout.save.assert_called_once_with()
        self.assertEqual(type(storage['address']), Address)
        self.assertEqual(storage['address'].first_name, 'Test')

    def test_address_save_with_address_in_checkout(self):
        self.request.POST = NEW_ADDRESS
        self.request.POST['email'] = 'test@gmail.com'
        self.checkout.billing_address = Address()
        storage = MagicMock()
        step = BillingAddressStep(self.checkout, self.request, storage)
        self.assertTrue(step.forms_are_valid(), 'Forms don\'t validate.')


class TestShippingStep(TestCase):

    def setUp(self):
        self.request = MagicMock()
        self.request.user.is_authenticated.return_value = False
        self.request.session = {}
        self.checkout = MagicMock()
        self.checkout.get_group.return_value = {}
        self.checkout.billing_address = None

    @patch.object(Address, 'save')
    def test_address_save_without_address(self, mock_save):
        self.request.POST = NEW_ADDRESS
        self.request.POST['method'] = 'dummy_shipping'
        self.request.session = {STORAGE_SESSION_KEY: {}}
        group = MagicMock()
        group.address = None
        storage = {}
        step = ShippingStep(self.checkout, self.request, storage, group)
        self.assertTrue(step.forms_are_valid(), 'Forms don\'t validate.')
        step.save()
        self.assertEqual(mock_save.call_count, 0)
        self.assertEqual(type(storage['address']), Address,
                         'Address instance expected')

    @patch.object(Address, 'save')
    def test_address_save_with_address_in_group(self, mock_save):
        self.request.POST = NEW_ADDRESS
        self.request.POST['method'] = 'dummy_shipping'
        group = MagicMock()
        group.address = Address()
        storage = MagicMock()
        step = ShippingStep(self.checkout, self.request, storage, group)
        self.assertTrue(step.forms_are_valid(), 'Forms don\'t validate.')
        step.save()
        self.assertEqual(mock_save.call_count, 0)

    @patch.object(Address, 'save')
    def test_address_save_with_address_in_checkout(self, mock_save):
        self.request.POST = NEW_ADDRESS
        self.request.POST['method'] = 'dummy_shipping'
        original_billing_address_data = {'first_name': 'Change',
                                         'last_name': 'Me',
                                         'id': 10}
        original_billing_address = Address(**original_billing_address_data)
        self.checkout.billing_address = original_billing_address
        group = MagicMock()
        group.address = None
        storage = {}
        step = ShippingStep(self.checkout, self.request, storage, group)
        self.assertTrue(step.forms_are_valid(), 'Forms don\'t validate.')
        step.save()
        self.assertEqual(mock_save.call_count, 0)
        self.assertEqual(self.checkout.billing_address,
                         Address(**original_billing_address_data))
        self.assertEqual(storage['address'].id, None)

@@ -847,32 +847,39 @@
 ST = NEW_ADDRESS
+.copy()
 %0A        step = 
@@ -890,39 +890,24 @@
 AddressStep(
-self.checkout, 
 self.request
@@ -1238,165 +1238,183 @@
 elf.
-checkout = MagicMock()%0A%0A    def test_address_save_without_address(self):%0A        self.checkout.billing_address = None%0A        self.request.POST = NEW_ADDRESS
+request.POST = NEW_ADDRESS.copy()%0A        self.request.POST%5B'email'%5D = 'test@example.com'%0A        self.checkout = MagicMock()%0A%0A    def test_address_save_without_address(self):
 %0A   
@@ -1461,39 +1461,24 @@
 AddressStep(
-self.checkout, 
 self.request
@@ -1540,61 +1540,8 @@
 ne)%0A
-        self.checkout.save.assert_called_once_with()%0A
     
@@ -1732,132 +1732,28 @@
    s
-elf.request.POST = NEW_ADDRESS%0A        self.request.POST%5B'email'%5D = 'test@gmail.com'%0A        self.checkout.billing_
+torage = %7B'
 address
- =
+':
  Add
@@ -1762,38 +1762,9 @@
 ss()
-%0A        storage = MagicMock()
+%7D
 %0A   
@@ -1790,39 +1790,24 @@
 AddressStep(
-self.checkout, 
 self.request
@@ -2340,32 +2340,39 @@
 ST = NEW_ADDRESS
+.copy()
 %0A        self.re
@@ -2570,39 +2570,24 @@
 hippingStep(
-self.checkout, 
 self.request
@@ -2995,32 +2995,39 @@
 ST = NEW_ADDRESS
+.copy()
 %0A        self.re
@@ -3146,27 +3146,18 @@
 orage = 
-MagicMock()
+%7B%7D
 %0A       
@@ -3173,39 +3173,24 @@
 hippingStep(
-self.checkout, 
 self.request
@@ -3495,16 +3495,23 @@
 _ADDRESS
+.copy()
 %0A       
@@ -3814,73 +3814,8 @@
 ta)%0A
-        self.checkout.billing_address = original_billing_address%0A
     
@@ -3878,32 +3878,67 @@
      storage = %7B
+'address': original_billing_address
 %7D%0A        step =
@@ -3955,23 +3955,8 @@
 tep(
-self.checkout, 
 self
@@ -4155,36 +4155,25 @@
 al(s
-elf.checkout.billing_
+torage%5B'
 address
+'%5D
 ,%0A  
@@ -4209,37 +4209,19 @@
 s(**
-original_billing_address_data
+NEW_ADDRESS
 ))%0A 

Fix tests