# Path: forums/models.py
# class Post(models.Model):
#     author = models.ForeignKey('auth.User', related_name='posts', editable=False)
# 
#     contents = models.TextField()
# 
#     contents_marked_up = models.TextField(editable=False, null=True)
# 
#     post_date = models.DateTimeField(editable=False)
# 
#     last_edit_date = models.DateTimeField(blank=True)
#     
#     # These fields apply to topics only #
#     
#     is_topic = models.BooleanField(default=False)
#     
#     title = models.CharField(max_length=120, blank=True, null=True)
#     
#     # Tags are stored in their own table, the IDs of those are here.
#     tag_ids = models.ManyToManyField(Tag, related_name='posts', blank=True)
# 
#     is_locked = models.NullBooleanField(blank=True)
# 
#     # END Topics only fields #
#     # These fields apply to replies only #
# 
#     reply_to = models.ForeignKey('Post', related_name='replies', blank=True, null=True, editable=False)
# 
#     # END Replies only fields #
# 
#     def was_edited(self):
#         return True if self.last_edit_date != self.post_date else False
#     
#     def __str__(self):
#         return "Reply to Topic {} (ID {})".format(str(self.reply_to), str(self.id)) if (self.title is None) or (
#             self.title == "") else self.title
# 
#     def save(self, *args, **kwargs):
#         now = timezone.now()
#         if not self.id:
#             self.post_date = now
#         self.last_edit_date = now
#         self.contents_marked_up = bleach.clean(markdown(self.contents).replace('\n', ''), settings.ALLOWED_TAGS,
#                                                settings.ALLOWED_ATTRIBUTES)
#         return super(Post, self).save(*args, **kwargs)
# 
# class Tag(models.Model):
#     name = models.CharField(max_length=40)
#     # Hex colours will be converted to an integer here for convenience
#     colour = models.IntegerField()
# 
#     def __str__(self):
#         return self.name
# 
# Path: forums/serializers.py
# class TopicSerializer(serializers.ModelSerializer):
#     reply_count = serializers.SerializerMethodField()
#     author_name = serializers.SerializerMethodField()
#     was_edited = serializers.SerializerMethodField()
#     avatar_url = serializers.SerializerMethodField()
#     can_edit = serializers.SerializerMethodField()
# 
#     class Meta:
#         model = Post
#         fields = ('id', 'title', 'tag_ids', 'author', 'author_name',
#                   'contents', 'post_date', 'last_edit_date', 'reply_count',
#                   'was_edited', 'avatar_url', 'contents_marked_up',
#                   'is_locked', 'can_edit')
# 
#         read_only_fields = ('replies',)
# 
#     def get_reply_count(self, obj):
#         return Post.objects.all().filter(reply_to=obj).count()
# 
#     def get_author_name(self, obj):
#         return obj.author.username
# 
#     def get_was_edited(self, obj):
#         return obj.was_edited()
# 
#     def get_avatar_url(self, obj):
#         emailhash = md5(obj.author.email.strip().lower().encode('utf-8')).hexdigest()
#         return "https://secure.gravatar.com/avatar/{}?d=identicon".format(emailhash)
# 
#     def get_can_edit(self, obj):
#         if self.context['request'].user.is_authenticated():
#             if self.context['request'].user.has_perm('forums.change_post', obj):
#                 return True
#             else:
#                 return False
#         return False
# 
# Path: forums/views.py
# class TagList(generics.ListCreateAPIView):
#     queryset = Tag.objects.all()
#     serializer_class = TagSerializer
#     throttle_classes = (StandardThrottle,)
#     permission_classes = (DjangoObjectPermissionsOrAnonReadOnly,)
# 
# class TopicDetail(generics.RetrieveUpdateDestroyAPIView):
#     queryset = Post.objects.all().filter(is_topic=True)
#     serializer_class = TopicSerializer
#     permission_classes = (DjangoObjectPermissionsOrAnonReadOnly,)
#     throttle_classes = (StandardThrottle,)
# 
# class AnyPostDetail(generics.RetrieveUpdateDestroyAPIView):
#     queryset = Post.objects.all()
#     serializer_class = PostOrTopicSerializer
#     permission_classes = (DjangoObjectPermissionsOrAnonReadOnly,)
#     throttle_classes = (StandardThrottle,)


from django.test import TestCase
from django.contrib.auth.models import User
from rest_framework.test import APIRequestFactory, force_authenticate
from .models import Post, Tag
from .serializers import TopicSerializer
from .views import TagList, TopicDetail, AnyPostDetail
        view = TopicDetail.as_view()
        response = view(request, pk=1)
        self.assertEqual(response.data['reply_count'], 2)

    def test_any_post_view(self):
        factory = APIRequestFactory()
        request = factory.get('/posts/3/', format='json')
        force_authenticate(request, user=User.objects.get_by_natural_key('admin'))
        view = AnyPostDetail.as_view()
        response = view(request, pk=3)
        self.assertEqual(response.data['contents'], 'Cool post!')


class LoadTestCase(TestCase):
    def setUp(self):
        User.objects.create_superuser('admin', 'fake@fakeness.net', 'null')
        u = User.objects.get_by_natural_key('admin')
        Post.objects.create(author=u, contents='test', is_topic=True, title='Testing...')

    def test_10k_replies(self):
        i = 0
        u = User.objects.get_by_natural_key('admin')
        t = Post.objects.get(id=1)
        while i < 10000:
            if i % 1000 == 0:
                print("Test 10,000 replies: At iteration {}".format(i))
            Post.objects.create(author=u, contents='test', reply_to=t)
            i += 1

        topic = Post.objects.get(id=1)

# Path: forums/models.py
# class Post(models.Model):
#     author = models.ForeignKey('auth.User', related_name='posts', editable=False)
# 
#     contents = models.TextField()
# 
#     contents_marked_up = models.TextField(editable=False, null=True)
# 
#     post_date = models.DateTimeField(editable=False)
# 
#     last_edit_date = models.DateTimeField(blank=True)
#     
#     # These fields apply to topics only #
#     
#     is_topic = models.BooleanField(default=False)
#     
#     title = models.CharField(max_length=120, blank=True, null=True)
#     
#     # Tags are stored in their own table, the IDs of those are here.
#     tag_ids = models.ManyToManyField(Tag, related_name='posts', blank=True)
# 
#     is_locked = models.NullBooleanField(blank=True)
# 
#     # END Topics only fields #
#     # These fields apply to replies only #
# 
#     reply_to = models.ForeignKey('Post', related_name='replies', blank=True, null=True, editable=False)
# 
#     # END Replies only fields #
# 
#     def was_edited(self):
#         return True if self.last_edit_date != self.post_date else False
#     
#     def __str__(self):
#         return "Reply to Topic {} (ID {})".format(str(self.reply_to), str(self.id)) if (self.title is None) or (
#             self.title == "") else self.title
# 
#     def save(self, *args, **kwargs):
#         now = timezone.now()
#         if not self.id:
#             self.post_date = now
#         self.last_edit_date = now
#         self.contents_marked_up = bleach.clean(markdown(self.contents).replace('\n', ''), settings.ALLOWED_TAGS,
#                                                settings.ALLOWED_ATTRIBUTES)
#         return super(Post, self).save(*args, **kwargs)
# 
# class Tag(models.Model):
#     name = models.CharField(max_length=40)
#     # Hex colours will be converted to an integer here for convenience
#     colour = models.IntegerField()
# 
#     def __str__(self):
#         return self.name
# 
# Path: forums/serializers.py
# class TopicSerializer(serializers.ModelSerializer):
#     reply_count = serializers.SerializerMethodField()
#     author_name = serializers.SerializerMethodField()
#     was_edited = serializers.SerializerMethodField()
#     avatar_url = serializers.SerializerMethodField()
#     can_edit = serializers.SerializerMethodField()
# 
#     class Meta:
#         model = Post
#         fields = ('id', 'title', 'tag_ids', 'author', 'author_name',
#                   'contents', 'post_date', 'last_edit_date', 'reply_count',
#                   'was_edited', 'avatar_url', 'contents_marked_up',
#                   'is_locked', 'can_edit')
# 
#         read_only_fields = ('replies',)
# 
#     def get_reply_count(self, obj):
#         return Post.objects.all().filter(reply_to=obj).count()
# 
#     def get_author_name(self, obj):
#         return obj.author.username
# 
#     def get_was_edited(self, obj):
#         return obj.was_edited()
# 
#     def get_avatar_url(self, obj):
#         emailhash = md5(obj.author.email.strip().lower().encode('utf-8')).hexdigest()
#         return "https://secure.gravatar.com/avatar/{}?d=identicon".format(emailhash)
# 
#     def get_can_edit(self, obj):
#         if self.context['request'].user.is_authenticated():
#             if self.context['request'].user.has_perm('forums.change_post', obj):
#                 return True
#             else:
#                 return False
#         return False
# 
# Path: forums/views.py
# class TagList(generics.ListCreateAPIView):
#     queryset = Tag.objects.all()
#     serializer_class = TagSerializer
#     throttle_classes = (StandardThrottle,)
#     permission_classes = (DjangoObjectPermissionsOrAnonReadOnly,)
# 
# class TopicDetail(generics.RetrieveUpdateDestroyAPIView):
#     queryset = Post.objects.all().filter(is_topic=True)
#     serializer_class = TopicSerializer
#     permission_classes = (DjangoObjectPermissionsOrAnonReadOnly,)
#     throttle_classes = (StandardThrottle,)
# 
# class AnyPostDetail(generics.RetrieveUpdateDestroyAPIView):
#     queryset = Post.objects.all()
#     serializer_class = PostOrTopicSerializer
#     permission_classes = (DjangoObjectPermissionsOrAnonReadOnly,)
#     throttle_classes = (StandardThrottle,)


# Path: forums/tests.py
from django.test import TestCase
from django.contrib.auth.models import User
from rest_framework.test import APIRequestFactory, force_authenticate
from .models import Post, Tag
from .serializers import TopicSerializer
from .views import TagList, TopicDetail, AnyPostDetail

        view = TopicDetail.as_view()
        response = view(request, pk=1)
        self.assertEqual(response.data['reply_count'], 2)

    def test_any_post_view(self):
        factory = APIRequestFactory()
        request = factory.get('/posts/3/', format='json')
        force_authenticate(request, user=User.objects.get_by_natural_key('admin'))
        view = AnyPostDetail.as_view()
        response = view(request, pk=3)
        self.assertEqual(response.data['contents'], 'Cool post!')


class LoadTestCase(TestCase):
    def setUp(self):
        User.objects.create_superuser('admin', 'fake@fakeness.net', 'null')
        u = User.objects.get_by_natural_key('admin')
        Post.objects.create(author=u, contents='test', is_topic=True, title='Testing...')

    def test_10k_replies(self):
        i = 0
        u = User.objects.get_by_natural_key('admin')
        t = Post.objects.get(id=1)
        while i < 10000:
            if i % 1000 == 0:
                print("Test 10,000 replies: At iteration {}".format(i))
            Post.objects.create(author=u, contents='test', reply_to=t)
            i += 1

        topic = Post.objects.get(id=1)

        serializer = TopicSerializer(topic)