"""
This file demonstrates writing tests using the unittest module. These will pass
when you run "manage.py test".

Replace this with more appropriate tests for your application.
"""

from django.test import TestCase
from django.test.client import Client
from django.test.client import RequestFactory
from django.test import LiveServerTestCase
# from selenium.webdriver.firefox.webdriver import WebDriver
from selenium.webdriver.chrome.webdriver import WebDriver

from contacts.models import Contact
from contacts.views import ListContactView


class SimpleTest(TestCase):
    def test_basic_addition(self):
        """
        Tests that 1 + 1 always equals 2.
        """
        self.assertEqual(1 + 1, 2)


class ContactTests(TestCase):
    """ Contact model tests. """

    def test_str(self):
        contact = Contact(first_name='Michael', last_name='Russo')

        self.assertEquals(str(contact), 'Michael Russo', )


class ContactListViewTests(TestCase):
    """Contact list view tests."""

    def test_contacts_in_the_context(self):
        client = Client()
        response = client.get('/')
        self.assertEquals(list(response.context['object_list']), [])

        Contact.objects.create(first_name='foo', last_name='bar')

        response = client.get('/')
        self.assertEquals(response.context['object_list'].count(), 1)

    def test_contacts_in_the_context_request_factory(self):
        factory = RequestFactory()
        request = factory.get('/')

        response = ListContactView.as_view()(request)

        self.assertEquals(list(response.context_data['object_list']), [])

        Contact.objects.create(first_name='foo', last_name='bar')
        response = ListContactView.as_view()(request)
        self.assertEquals(response.context_data['object_list'].count(), 1)


class ContactListIntegrationTests(LiveServerTestCase):
    @classmethod
    def setUpClass(cls):
        cls.selenium = WebDriver('/usr/local/bin/chromedriver')

        super(ContactListIntegrationTests, cls).setUpClass()

    @classmethod
    def tearDownClass(cls):
        cls.selenium.quit()
        super(ContactListIntegrationTests, cls).tearDownClass()

    def test_contact_listed(self):
        # create a test contact
        Contact.objects.create(first_name='foo', last_name='bar')

        # make sure its listed as <first> <last> on the list
        self.selenium.get('%s%s' % (self.live_server_url, '/'))
        self.assertEqual(self.selenium.find_elements_by_css_selector('.contact')[0].text, 'foo bar (edit)')

    def test_add_contact_linked(self):
        self.selenium.get('%s%s' % (self.live_server_url, '/'))
        self.assert_(self.selenium.find_element_by_link_text('add contact'))

    def test_add_contact(self):
        self.selenium.get('%s%s' % (self.live_server_url, '/'))
        self.selenium.find_element_by_link_text('add contact').click()
        self.selenium.find_element_by_id('id_first_name').send_keys('test')
        self.selenium.find_element_by_id('id_last_name').send_keys('contact')
        self.selenium.find_element_by_id('id_email').send_keys('test@example.com')

        self.selenium.find_element_by_id('save_contact').click()
        self.assertEqual(self.selenium.find_elements_by_css_selector('.contact')[-1].text, 'test contact (edit)')

    def test_detail_view_contact(self):
        # create a test contact
        Contact.objects.create(first_name='test', last_name='contact', email='test@example.com')

        self.selenium.get('%s%s' % (self.live_server_url, '/'))
        self.selenium.find_element_by_link_text('test contact').click()

        h1_title = self.selenium.find_element_by_tag_name('h1').text
        self.assertEqual(h1_title, 'test contact')

        contact_email = self.selenium.find_elements_by_tag_name('p')[0].text
        self.assertEqual(contact_email, 'Email: test@example.com')

    def test_update_contact(self):
        # create a test contact
        Contact.objects.create(first_name='test', last_name='contact', email='test@example.com')

        self.selenium.get('%s%s' % (self.live_server_url, '/'))
        self.selenium.find_element_by_link_text('edit').click()
        self.selenium.find_element_by_id('id_first_name').send_keys(' updated')
        self.selenium.find_element_by_id('id_last_name').send_keys(' updated')
        email = self.selenium.find_element_by_id('id_email')
        email.clear()
        email.send_keys('test-updated@example.com')

        self.selenium.find_element_by_id('save_contact').click()
        self.assertEqual(self.selenium.find_elements_by_css_selector('.contact')[-1].text,
                         'test updated contact updated (edit)')

    def test_delete_contact(self):
        # create a test contact
        Contact.objects.create(first_name='test', last_name='contact', email='test@example.com')

        self.selenium.get('%s%s' % (self.live_server_url, '/'))
        self.selenium.find_element_by_link_text('edit').click()

        self.selenium.find_element_by_link_text('Delete').click()
        self.selenium.find_elements_by_tag_name('input')[1].click()

        exists = len(self.selenium.find_elements_by_link_text('test contact')) > 0
        self.assertFalse(exists)

