from datetime import datetime
from unittest2 import TestCase
from os import path

import pytz
from mock import patch

from ug import app
from ug.util import ical


def _load_calendar():
    ical_file = path.join(path.dirname(path.abspath(__file__)), 'ical.ics')
    ical_contents = open(ical_file).read()
    cal = ical.Calendar.from_ical(ical_contents)
    return cal


@patch('ug.util.ical._load_calendar', new=_load_calendar)
@patch('ug.util.ical._now',
       return_value=datetime(2014, 11, 18, 8, 24, 7, tzinfo=pytz.utc))
class IcalTestCase(TestCase):

    def setUp(self):

        self.cal = _load_calendar()
        self.event_pub, self.event_dojo = ical.upcoming_events(cal=self.cal)

    def test_upcoming_events(self, mock_now):

        pub, dojo = ical.upcoming_events()
        url = 'http://attending.io/events/pythonglasgow-dojo-december-2014'

        self.assertEquals(dojo.title, "Coding Dojo")
        self.assertEquals(
            dojo.start, datetime(2014, 12, 9, 18, 30, 00, tzinfo=pytz.utc))
        self.assertEquals(dojo.where, "Twig World, 14 N Claremont St, G3 7Le")
        self.assertEquals(dojo.description, "")
        self.assertEquals(dojo.metadata, {
            'type': 'dojo',
            'link': url,
        })

        self.assertEquals(pub.title, "Pub Meetup")
        self.assertEquals(
            pub.start, datetime(2014, 11, 19, 18, 30, 00, tzinfo=pytz.utc))
        self.assertEquals(pub.where, ("The Raven Glasgow, 81-85 Renfield St, "
                                      "Glasgow G2 1Nq, United Kingdom"))
        self.assertEquals(pub.description, "")
        self.assertEquals(pub.metadata, {
            'type': 'pub',
        })

    def test_days_until_next_event(self, mock_now):

        days, event = ical.days_until_next_event()

        self.assertEquals(1, days)
        self.assertEquals(event.title, self.event_pub.title)
        self.assertEquals(event.start, self.event_pub.start)

        self.assertEquals(21, self.event_dojo.days_until())

    def test_days_until_next_event_none(self, mock_now):

        mock_now.return_value = datetime(
            2015, 11, 18, 8, 24, 7, tzinfo=pytz.utc)

        with self.assertRaises(ical.NoEvents):
            ical.days_until_next_event()

    @patch('flask_mail._MailMixin.send')
    @patch('ug.util.ical.days_until_next_event')
    def test_mail_events_noop(self, mock_days_until, mock_send, mock_now):

        mock_days_until.return_value = (20, self.event_pub)

        ical.mail_events('test@test.com')

        assert not mock_send.called

    @patch('flask_mail._MailMixin.send')
    @patch('ug.util.ical.days_until_next_event')
    def test_mail_events_admin(self, mock_days_until, mock_send, mock_now):

        mock_days_until.return_value = (
            app.config['ADMIN_REMINDER_DAYS'], self.event_pub
        )

        with app.test_request_context('/send_email'):
            ical.mail_events('test@test.com')

        mock_send.assert_called_once()

    @patch('flask_mail._MailMixin.send')
    @patch('ug.util.ical.days_until_next_event')
    def test_mail_events_list(self, mock_days_until, mock_send, mock_now):

        mock_days_until.return_value = (
            app.config['LIST_REMINDER_DAYS'], self.event_pub
        )

        with app.test_request_context('/send_email'):
            ical.mail_events('test@test.com')

        mock_send.assert_called_once()

    @patch('flask_mail.Mail.send')
    def test_mail_no_events(self, mock_now, mock_send):

        with app.test_request_context('/send_email'):
            ical.mail_events('test@test.com')

        mock_send.assert_called_once()

@@ -368,67 +368,86 @@
 l%0A%0A%0A
-@patch('ug.util.ical._load_calendar', new=_load_calendar)%0A@
+class IcalTestCase(TestCase):%0A%0A    def setUp(self):%0A%0A        self.now_patch = 
 patc
@@ -469,16 +469,40 @@
 ._now',%0A
+                        
        r
@@ -549,78 +549,284 @@
 , 7,
- tzinfo=pytz.utc))%0Aclass IcalTestCase(TestCase):%0A%0A    def setUp(self):
+%0A                                                     tzinfo=pytz.utc))%0A        self.now_patch.start()%0A        self.load_calendar_patch = patch('ug.util.ical._load_calendar',%0A                                         new=_load_calendar)%0A        self.load_calendar_patch.start()
 %0A%0A  
@@ -937,16 +937,111 @@
 f.cal)%0A%0A
+    def tearDown(self):%0A        self.now_patch.stop()%0A        self.load_calendar_patch.stop()%0A%0A
     def 
@@ -1061,34 +1061,24 @@
 _events(self
-, mock_now
 ):%0A%0A        
@@ -2049,34 +2049,24 @@
 t_event(self
-, mock_now
 ):%0A%0A        
@@ -2372,26 +2372,16 @@
 one(self
-, mock_now
 ):%0A%0A    
@@ -2388,17 +2388,59 @@
     
-mock_now.
+with patch('ug.util.ical._now',%0A                   
 retu
@@ -2447,19 +2447,17 @@
 rn_value
- = 
+=
 datetime
@@ -2457,29 +2457,16 @@
 atetime(
-%0A            
 2015, 11
@@ -2480,16 +2480,57 @@
 , 24, 7,
+%0A                                        
  tzinfo=
@@ -2538,18 +2538,23 @@
 ytz.utc)
-%0A%0A
+):%0A    
         
@@ -2592,16 +2592,20 @@
 vents):%0A
+    
         
@@ -2786,34 +2786,24 @@
 l, mock_send
-, mock_now
 ):%0A%0A        
@@ -3084,34 +3084,24 @@
 l, mock_send
-, mock_now
 ):%0A%0A        
@@ -3499,26 +3499,16 @@
 ock_send
-, mock_now
 ):%0A%0A    
@@ -3829,18 +3829,8 @@
 elf,
- mock_now,
  moc

Fix broken mocks