# Path: dwitter/feed/views.py
# class NewUserFeed(UserFeed):
#     sort = SortMethod.NEW
#     feed_name = "new"
# 
#     def get_title(self):
#         return "Dweets by u/" + self.kwargs['url_username'] + " | Dwitter"
# 
# class TopUserFeed(UserFeed):
#     sort = SortMethod.TOP
#     feed_name = "top"
# 
#     def get_title(self):
#         return "Top dweets by u/" + self.kwargs['url_username'] + " | Dwitter"
# 
# class HotUserFeed(UserFeed):
#     sort = SortMethod.HOT
#     feed_name = "hot"
# 
#     def get_title(self):
#         return "Hot dweets by u/" + self.kwargs['url_username'] + " | Dwitter"
# 
# class NewLikedFeed(LikedFeed):
#     sort = SortMethod.NEW
#     feed_name = "awesome"
# 
#     def get_title(self):
#         return "Dweets awesomed by u/" + self.kwargs['url_username'] + " | Dwitter"
# 
# Path: dwitter/models.py
# class Dweet(models.Model):
#     code = models.TextField()
#     posted = models.DateTimeField(db_index=True)
#     reply_to = models.ForeignKey("self", on_delete=models.DO_NOTHING,
#                                  related_name="remixes", null=True, blank=True)
# 
#     likes = models.ManyToManyField(User, related_name="liked", blank=True)
#     hotness = models.FloatField(default=1.0, db_index=True)
#     deleted = models.BooleanField(default=False)
# 
#     author = models.ForeignKey(User, on_delete=models.SET(get_sentinel_user),
#                                null=True, blank=True)
# 
#     objects = NotDeletedDweetManager()
#     with_deleted = models.Manager()
# 
#     class Meta:
#         ordering = ('-posted',)
# 
#     def delete(self):
#         self.deleted = True
#         self.save()
# 
#     def save(self, *args, **kwargs):
#         self.calculate_hotness((self.pk is None))
#         super(Dweet, self).save(*args, **kwargs)
# 
#     @cached_property
#     def top_comment(self):
#         """
#         Return the top comment. This is mainly a caching optimization to avoid queries
#         """
#         return self.comments.first()
# 
#     @cached_property
#     def dweet_length(self):
#         return length_of_code(self.code)
# 
#     @cached_property
#     def has_sticky_comment(self):
#         """
#         True when first comment should be stickied (first comment author == dweet author)
#         """
#         if self.top_comment is None:
#             return False
#         return self.top_comment.author == self.author
# 
#     def __str__(self):
#         return 'd/' + str(self.id) + ' (' + self.author.username + ')'
# 
#     def calculate_hotness(self, is_new):
#         """
#         Hotness is inspired by the Hackernews ranking algorithm
#         Read more here:
#         https://medium.com/hacking-and-gonzo/how-hacker-news-ranking-algorithm-works-1d9b0cf2c08d
#         """
#         def epoch_seconds(date):
#             epoch = datetime(2015, 5, 5)  # arbitrary start date before Dwitter existed
#             naive = date.replace(tzinfo=None)
#             td = naive - epoch
#             return td.days * 86400 + td.seconds + (float(td.microseconds) / 1000000)
# 
#         likes = 1
#         if not is_new:
#             likes = max(self.likes.count(), 1)
# 
#         order = log(likes, 2)
#         # 86400 seconds = 24 hours.
#         # So for every log(2) likes on a dweet, its effective
#         # "posted time" moves 24 forward
#         # In other words, it takes log2(likes) * 24hrs before
#         # a dweet with a single like beat yours
#         self.hotness = round(order + epoch_seconds(self.posted)/86400, 7)


import random
from django.test import TestCase
from dwitter.feed.views import NewUserFeed, TopUserFeed, HotUserFeed, NewLikedFeed
from dwitter.models import Dweet
from django.test.client import RequestFactory
from django.contrib.auth.models import User
from django.utils import timezone
from datetime import timedelta

    def test_all_dweet_author(self):
        self.dweetFeed.kwargs = {'url_username': self.users[3].username}
        queryset = self.dweetFeed.get_queryset()
        for dweet in queryset:
            self.assertEqual(self.users[3], dweet.author)

    def test_queryset_size(self):
        self.dweetFeed.kwargs = {'url_username': self.users[1].username}
        queryset = self.dweetFeed.get_queryset()
        # Each user have 10 dweets from setUp
        self.assertEqual(queryset.count(), 10)


class NewUserFeedTests(UserFeedTestCase, TestCase):
    dweetFeed = NewUserFeed()


class TopUserFeedTests(UserFeedTestCase, TestCase):
    dweetFeed = TopUserFeed()

    def test_annotation(self):
        self.dweetFeed.kwargs = {'url_username': self.users[1].username}
        queryset = self.dweetFeed.get_queryset()
        for dweet in queryset:
            num_likes = dweet.num_likes
            self.assertEqual(num_likes, dweet.likes.count())


class HotUserFeedTests(UserFeedTestCase, TestCase):

# Path: dwitter/feed/views.py
# class NewUserFeed(UserFeed):
#     sort = SortMethod.NEW
#     feed_name = "new"
# 
#     def get_title(self):
#         return "Dweets by u/" + self.kwargs['url_username'] + " | Dwitter"
# 
# class TopUserFeed(UserFeed):
#     sort = SortMethod.TOP
#     feed_name = "top"
# 
#     def get_title(self):
#         return "Top dweets by u/" + self.kwargs['url_username'] + " | Dwitter"
# 
# class HotUserFeed(UserFeed):
#     sort = SortMethod.HOT
#     feed_name = "hot"
# 
#     def get_title(self):
#         return "Hot dweets by u/" + self.kwargs['url_username'] + " | Dwitter"
# 
# class NewLikedFeed(LikedFeed):
#     sort = SortMethod.NEW
#     feed_name = "awesome"
# 
#     def get_title(self):
#         return "Dweets awesomed by u/" + self.kwargs['url_username'] + " | Dwitter"
# 
# Path: dwitter/models.py
# class Dweet(models.Model):
#     code = models.TextField()
#     posted = models.DateTimeField(db_index=True)
#     reply_to = models.ForeignKey("self", on_delete=models.DO_NOTHING,
#                                  related_name="remixes", null=True, blank=True)
# 
#     likes = models.ManyToManyField(User, related_name="liked", blank=True)
#     hotness = models.FloatField(default=1.0, db_index=True)
#     deleted = models.BooleanField(default=False)
# 
#     author = models.ForeignKey(User, on_delete=models.SET(get_sentinel_user),
#                                null=True, blank=True)
# 
#     objects = NotDeletedDweetManager()
#     with_deleted = models.Manager()
# 
#     class Meta:
#         ordering = ('-posted',)
# 
#     def delete(self):
#         self.deleted = True
#         self.save()
# 
#     def save(self, *args, **kwargs):
#         self.calculate_hotness((self.pk is None))
#         super(Dweet, self).save(*args, **kwargs)
# 
#     @cached_property
#     def top_comment(self):
#         """
#         Return the top comment. This is mainly a caching optimization to avoid queries
#         """
#         return self.comments.first()
# 
#     @cached_property
#     def dweet_length(self):
#         return length_of_code(self.code)
# 
#     @cached_property
#     def has_sticky_comment(self):
#         """
#         True when first comment should be stickied (first comment author == dweet author)
#         """
#         if self.top_comment is None:
#             return False
#         return self.top_comment.author == self.author
# 
#     def __str__(self):
#         return 'd/' + str(self.id) + ' (' + self.author.username + ')'
# 
#     def calculate_hotness(self, is_new):
#         """
#         Hotness is inspired by the Hackernews ranking algorithm
#         Read more here:
#         https://medium.com/hacking-and-gonzo/how-hacker-news-ranking-algorithm-works-1d9b0cf2c08d
#         """
#         def epoch_seconds(date):
#             epoch = datetime(2015, 5, 5)  # arbitrary start date before Dwitter existed
#             naive = date.replace(tzinfo=None)
#             td = naive - epoch
#             return td.days * 86400 + td.seconds + (float(td.microseconds) / 1000000)
# 
#         likes = 1
#         if not is_new:
#             likes = max(self.likes.count(), 1)
# 
#         order = log(likes, 2)
#         # 86400 seconds = 24 hours.
#         # So for every log(2) likes on a dweet, its effective
#         # "posted time" moves 24 forward
#         # In other words, it takes log2(likes) * 24hrs before
#         # a dweet with a single like beat yours
#         self.hotness = round(order + epoch_seconds(self.posted)/86400, 7)


# Path: dwitter/tests/feed/test_user_feeds.py
import random
from django.test import TestCase
from dwitter.feed.views import NewUserFeed, TopUserFeed, HotUserFeed, NewLikedFeed
from dwitter.models import Dweet
from django.test.client import RequestFactory
from django.contrib.auth.models import User
from django.utils import timezone
from datetime import timedelta


    def test_all_dweet_author(self):
        self.dweetFeed.kwargs = {'url_username': self.users[3].username}
        queryset = self.dweetFeed.get_queryset()
        for dweet in queryset:
            self.assertEqual(self.users[3], dweet.author)

    def test_queryset_size(self):
        self.dweetFeed.kwargs = {'url_username': self.users[1].username}
        queryset = self.dweetFeed.get_queryset()
        # Each user have 10 dweets from setUp
        self.assertEqual(queryset.count(), 10)


class NewUserFeedTests(UserFeedTestCase, TestCase):
    dweetFeed = NewUserFeed()


class TopUserFeedTests(UserFeedTestCase, TestCase):
    dweetFeed = TopUserFeed()

    def test_annotation(self):
        self.dweetFeed.kwargs = {'url_username': self.users[1].username}
        queryset = self.dweetFeed.get_queryset()
        for dweet in queryset:
            num_likes = dweet.num_likes
            self.assertEqual(num_likes, dweet.likes.count())


class HotUserFeedTests(UserFeedTestCase, TestCase):

    dweetFeed = HotUserFeed()