"""Run: venv/bin/python manage.py test apps.engage"""
from django.contrib.auth.models import User
from django.test import TestCase, override_settings

from apps.articles.models import Article

from .models import Comment, Rating, Reaction


@override_settings(ALLOWED_HOSTS=['testserver'])
class EngageTests(TestCase):
    def setUp(self):
        from django.utils import timezone
        self.a = Article.objects.create(title='Bhisti', slug='bhisti', body='<p>x</p>', excerpt='x', status='published',
                                        featured_image='articles/x.jpg')
        Article.objects.filter(pk=self.a.pk).update(published_at=timezone.now())
        self.u = User.objects.create_user('rahim', 'rahim@example.com', 'pw-12345678', first_name='Rahim')
        self.ajax = {'HTTP_X_REQUESTED_WITH': 'XMLHttpRequest'}

    def test_guests_are_asked_to_sign_in(self):
        page = self.client.get('/articles/bhisti/')
        self.assertContains(page, 'লাইক, সেভ, রেটিং আর মন্তব্য করতে সাইন ইন করুন')
        r = self.client.post(f'/engage/article/{self.a.pk}/react/like/')
        self.assertEqual(r.status_code, 302)
        self.assertIn('/account/login/', r['Location'])
        self.assertEqual(self.client.post(f'/engage/article/{self.a.pk}/react/like/', **self.ajax).status_code, 401)
        self.assertEqual(Reaction.objects.count(), 0)

    def test_like_save_rate_comment(self):
        self.client.login(username='rahim', password='pw-12345678')
        d = self.client.post(f'/engage/article/{self.a.pk}/react/like/', **self.ajax).json()
        self.assertEqual((d['likes'], d['liked']), (1, True))
        d = self.client.post(f'/engage/article/{self.a.pk}/react/like/', **self.ajax).json()
        self.assertEqual(d['likes'], 0)  # toggles off
        self.client.post(f'/engage/article/{self.a.pk}/react/save/', **self.ajax)
        self.client.post(f'/engage/article/{self.a.pk}/rate/', {'stars': 4}, **self.ajax)
        d = self.client.post(f'/engage/article/{self.a.pk}/rate/', {'stars': 5}, **self.ajax).json()
        self.assertEqual((d['rating_count'], d['my_stars']), (1, 5))
        d = self.client.post(f'/engage/article/{self.a.pk}/comment/', {'body': 'দারুণ লেখা!'}, **self.ajax).json()
        self.assertEqual(d['comment_count'], 1)
        self.client.post(f'/engage/article/{self.a.pk}/comment/', {'body': 'see http://spam.example'}, **self.ajax)
        self.assertEqual(Comment.objects.get(body__contains='spam').status, 'pending')
        page = self.client.get('/articles/bhisti/').content.decode()
        self.assertIn('দারুণ লেখা!', page)
        self.assertNotIn('spam.example', page)
        self.assertIn('Bhisti', self.client.get('/articles/reading-list/').content.decode())
        self.assertContains(self.client.get('/account/'), 'Saved for later')

    def test_cannot_touch_unpublished_or_others_comments(self):
        self.client.login(username='rahim', password='pw-12345678')
        Article.objects.filter(pk=self.a.pk).update(status='draft')
        self.assertEqual(self.client.post(f'/engage/article/{self.a.pk}/react/like/').status_code, 404)
        Article.objects.filter(pk=self.a.pk).update(status='published')
        other = User.objects.create_user('x', 'x@example.com', 'pw-12345678')
        from .registry import ct
        c = Comment.objects.create(user=other, content_type=ct(self.a), object_id=self.a.pk, body='hello')
        self.assertEqual(self.client.post(f'/engage/comment/{c.pk}/delete/').status_code, 404)
        self.assertEqual(self.client.post(f'/engage/article/{self.a.pk}/rate/', {'stars': 9}, **self.ajax).status_code, 400)
        self.assertEqual(Rating.objects.count(), 0)
