# Path: tidings/models.py
# class WatchFilter(ModelBase):
#     """Additional key/value pairs that pare down the scope of a watch"""
# 
#     watch = models.ForeignKey(Watch, related_name='filters',
#                               on_delete=models.CASCADE)
#     name = models.CharField(max_length=20)
# 
#     #: Either an int or the hash of an item in a reasonably small set, which is
#     #: indicated by the name field. See comments by
#     #: :func:`~tidings.utils.hash_to_unsigned()` for more on what is reasonably
#     #: small.
#     value = models.PositiveIntegerField()
# 
#     class Meta(object):
#         # There's no particular reason we couldn't allow multiple values for
#         # one name to be ORed together, but the API needs a little work
#         # (accepting lists passed to notify()) to support that.
#         #
#         # This ordering makes the index usable for lookups by name.
#         unique_together = ('name', 'watch')
# 
#     def __unicode__(self):
#         return u'WatchFilter %s: %s=%s' % (self.pk, self.name, self.value)
# 
# class EmailUser(AnonymousUser):
#     """An anonymous user identified only by email address.
# 
#     This is based on Django's AnonymousUser, so you can use the
#     ``is_authenticated`` property to tell that this is an anonymous user.
#     """
#     def __init__(self, email=''):
#         self.email = email
# 
#     def __unicode__(self):
#         return 'Anonymous user <%s>' % self.email
# 
#     __repr__ = AnonymousUser.__str__
# 
#     def __eq__(self, other):
#         return self.email == other.email
# 
#     def __ne__(self, other):
#         return self.email != other.email
# 
#     def __hash__(self):
#         return hash(self.email)
# 
# Path: tests/base.py
# def watch(save=False, **kwargs):
#     # TODO: better defaults, when there are events available.
#     defaults = {'user': kwargs.get('user') or user(save=True),
#                 'is_active': True,
#                 'secret': 'abcdefghjk'}
#     defaults.update(kwargs)
#     w = Watch.objects.create(**defaults)
#     if save:
#         w.save()
#     return w
# 
# def watch_filter(save=False, **kwargs):
#     defaults = {'watch': kwargs.get('watch') or watch(save=True),
#                 'name': 'test',
#                 'value': 1234}
#     defaults.update(kwargs)
#     f = WatchFilter.objects.create(**defaults)
#     if save:
#         f.save()
#     return f


from django.test import TestCase
from tidings.models import WatchFilter, EmailUser
from .base import watch, watch_filter



# TODO: write a test to ensure that event types don't collide
# case-insensitive-ly
# E.g. No duplicates in this list: [et.lower() for et in EVENT_TYPES]


class WatchTests(TestCase):
    """Tests for Watch model"""

    def test_unsubscribe_url(self):
        """Make sure unsubscribe_url() returns something URL-ish."""
        w = watch()
        url = w.unsubscribe_url()
        assert url.startswith('http')
        assert url.endswith('?s=%s' % w.secret)


class WatchFilterTests(TestCase):
    """Tests for WatchFilter"""

    def test_value_range(self):
        """Assert 0 and 2**32-1 both fit in the value field.

        That's the range of our hash function.

        """
        MAX_INT = 2 ** 32 - 1
        watch_filter(name='maxint', value=MAX_INT).save()

# Path: tidings/models.py
# class WatchFilter(ModelBase):
#     """Additional key/value pairs that pare down the scope of a watch"""
# 
#     watch = models.ForeignKey(Watch, related_name='filters',
#                               on_delete=models.CASCADE)
#     name = models.CharField(max_length=20)
# 
#     #: Either an int or the hash of an item in a reasonably small set, which is
#     #: indicated by the name field. See comments by
#     #: :func:`~tidings.utils.hash_to_unsigned()` for more on what is reasonably
#     #: small.
#     value = models.PositiveIntegerField()
# 
#     class Meta(object):
#         # There's no particular reason we couldn't allow multiple values for
#         # one name to be ORed together, but the API needs a little work
#         # (accepting lists passed to notify()) to support that.
#         #
#         # This ordering makes the index usable for lookups by name.
#         unique_together = ('name', 'watch')
# 
#     def __unicode__(self):
#         return u'WatchFilter %s: %s=%s' % (self.pk, self.name, self.value)
# 
# class EmailUser(AnonymousUser):
#     """An anonymous user identified only by email address.
# 
#     This is based on Django's AnonymousUser, so you can use the
#     ``is_authenticated`` property to tell that this is an anonymous user.
#     """
#     def __init__(self, email=''):
#         self.email = email
# 
#     def __unicode__(self):
#         return 'Anonymous user <%s>' % self.email
# 
#     __repr__ = AnonymousUser.__str__
# 
#     def __eq__(self, other):
#         return self.email == other.email
# 
#     def __ne__(self, other):
#         return self.email != other.email
# 
#     def __hash__(self):
#         return hash(self.email)
# 
# Path: tests/base.py
# def watch(save=False, **kwargs):
#     # TODO: better defaults, when there are events available.
#     defaults = {'user': kwargs.get('user') or user(save=True),
#                 'is_active': True,
#                 'secret': 'abcdefghjk'}
#     defaults.update(kwargs)
#     w = Watch.objects.create(**defaults)
#     if save:
#         w.save()
#     return w
# 
# def watch_filter(save=False, **kwargs):
#     defaults = {'watch': kwargs.get('watch') or watch(save=True),
#                 'name': 'test',
#                 'value': 1234}
#     defaults.update(kwargs)
#     f = WatchFilter.objects.create(**defaults)
#     if save:
#         f.save()
#     return f


# Path: tests/test_models.py
from django.test import TestCase
from tidings.models import WatchFilter, EmailUser
from .base import watch, watch_filter




# TODO: write a test to ensure that event types don't collide
# case-insensitive-ly
# E.g. No duplicates in this list: [et.lower() for et in EVENT_TYPES]


class WatchTests(TestCase):
    """Tests for Watch model"""

    def test_unsubscribe_url(self):
        """Make sure unsubscribe_url() returns something URL-ish."""
        w = watch()
        url = w.unsubscribe_url()
        assert url.startswith('http')
        assert url.endswith('?s=%s' % w.secret)


class WatchFilterTests(TestCase):
    """Tests for WatchFilter"""

    def test_value_range(self):
        """Assert 0 and 2**32-1 both fit in the value field.

        That's the range of our hash function.

        """
        MAX_INT = 2 ** 32 - 1
        watch_filter(name='maxint', value=MAX_INT).save()

        self.assertEqual(MAX_INT, WatchFilter.objects.get(name='maxint').value)