from datetime import date, timedelta

from django.test import TestCase, Client
from django.utils import timezone

from mtp.apps.accounts.factories import MTPUserFactory

from .helpers import (
    count_registrations,
    day_range,
)


class StatisticsHelpersTestCase(TestCase):
    """Tests for the helpers used in the `analytics` page"""

    def setUp(self):
        super().setUp()

        self.client = Client()

    @classmethod
    def setUpTestData(cls):
        super().setUpTestData()

        cls.date_start = timezone.now()
        cls.date_end = timezone.now() + timedelta(1)

        # The dict of data we should expect
        cls.expected_initial_data = {
            'title': 0,
            'graph': [
                {
                    'nb_event': 0,
                    'date': cls.date_start.strftime('%d/%m/%Y')
                }
            ]
        }

        cls.expected_after_data = {
            'title': 1,
            'graph': [
                {
                    'nb_event': 1,
                    'date': cls.date_start.strftime('%d/%m/%Y')
                }
            ]
        }

    def test_count_registrations(self):
        """Test if the count_registrations helper correctly report the
        count_registration of users
        """

        # We got no data
        self.assertEqual(
            count_registrations(self.date_start, self.date_end),
            self.expected_initial_data
        )

        # We register a user
        MTPUserFactory()

        # We should get a new registration event in the logs
        self.assertEqual(
            count_registrations(self.date_start, self.date_end),
            self.expected_after_data
        )

    def test_day_range(self):
        """Test that the ``day_range`` function returns the correct list of dates."""

        # One day
        result = tuple(day_range(date(2015, 6, 1), date(2015, 6, 1)))
        self.assertTupleEqual(result, (date(2015, 6, 1),))

        # Two consecutive days
        result = tuple(day_range(date(2015, 6, 1), date(2015, 6, 2)))
        self.assertTupleEqual(result, (date(2015, 6, 1), date(2015, 6, 2)))

        # Longer period
        result = tuple(day_range(date(2015, 6, 1), date(2015, 6, 3)))
        self.assertTupleEqual(result, (date(2015, 6, 1), date(2015, 6, 2), date(2015, 6, 3)))

        # No matching dates
        result = tuple(day_range(date(2015, 6, 3), date(2015, 6, 1)))
        self.assertTupleEqual(result, ())

        # Check that we have an iterator
        # pylint: disable=redefined-variable-type
        result = day_range(date(2015, 6, 1), date(2015, 6, 3))
        self.assertEqual(next(result), date(2015, 6, 1))
        self.assertEqual(next(result), date(2015, 6, 2))
        self.assertEqual(next(result), date(2015, 6, 3))
        with self.assertRaises(StopIteration):
            next(result)
