from django.contrib.auth.models import User
from django.core.urlresolvers import reverse
from django.test import TestCase

from .models import Post


class TestPostReadViews(TestCase):

    """
    Тестуємо головну сторінку блога і сторінки перегляду постів
    """

    fixtures = ['blog/fixtures/sample_blog_posts.json']

    def test_viewable_blog_main_page(self):
        response = self.client.get(reverse('blog'))
        self.assertEqual(response.status_code, 200)

    def test_viewable_post_list_pages(self):
        page1 = self.client.get(reverse('post_list', kwargs={'page': 1}))
        self.assertEqual(page1.status_code, 200)

        page2 = self.client.get(reverse('post_list', kwargs={'page': 2}))
        self.assertEqual(page2.status_code, 200)

    def test_viewable_post_detail(self):
        first_post = self.client.get(reverse('post_detail', kwargs={'pk': 1}))
        self.assertEqual(first_post.status_code, 200)
        self.assertContains(first_post, 'Kyocera', status_code=200)


class TestPostsEditViews(TestCase):

    """
    Тестуємо сторінки редагування, створення і видалення постів
    """

    fixtures = ['blog/fixtures/sample_blog_posts.json']

    def setUp(self):
        self.staff = User.objects.create_user(username='staff',
                                              email='staff@gmail.com',
                                              password='staff')
        self.staff.is_staff = True
        self.staff.save()

        self.joe = User.objects.create_user(username='joe',
                                            email='joe@gmail.com',
                                            password='qwerty')
        self.staff.is_staff = True
        self.staff.save()

    def test_post_create_page_not_viewable_by_anonymous_user(self):
        post_create_url = reverse('post_create')
        login_url = reverse('admin:login') + '?next=' + post_create_url

        response = self.client.get(post_create_url)
        self.assertRedirects(response, login_url)

    def test_post_create_page_not_viewable_by_regular_user(self):
        post_create_url = reverse('post_create')
        login_url = reverse('admin:login') + '?next=' + post_create_url

        self.client.login(username='joe', password='qwerty')
        response = self.client.get(post_create_url)
        self.assertRedirects(response, login_url)

    def test_post_create_page_viewable_by_staff(self):
        post_create_url = reverse('post_create')
        self.client.login(username='staff', password='staff')
        response = self.client.get(post_create_url)
        self.assertEqual(response.status_code, 200)

    def test_post_create(self):
        post_data = {
            'title': 'Test post',
            'description': 'Empty description',
            'content': 'Test content',
            'category': 1
        }

        self.client.login(username='staff', password='staff')
        response = self.client.post(reverse('post_create'), post_data)
        post = Post.objects.get(**post_data)

        self.assertRedirects(response, post.get_absolute_url())

    def test_post_update_page_not_viewable_by_anonymous_user(self):
        post_update_url = reverse('post_update', kwargs={'pk': 1})
        login_url = reverse('admin:login') + '?next=' + post_update_url

        response = self.client.get(post_update_url)
        self.assertRedirects(response, login_url)

    def test_post_update_page_not_viewable_by_regular_user(self):
        post_update_url = reverse('post_update', kwargs={'pk': 1})
        login_url = reverse('admin:login') + '?next=' + post_update_url

        self.client.login(username='joe', password='qwerty')
        response = self.client.get(post_update_url)
        self.assertRedirects(response, login_url)

    def test_post_update_page_viewable_by_staff(self):
        post_update_url = reverse('post_update', kwargs={'pk': 1})

        self.client.login(username='staff', password='staff')
        response = self.client.get(post_update_url)
        self.assertEqual(response.status_code, 200)

    def test_post_update(self):
        post_data = {
            'title': 'Test post',
            'description': 'Empty description',
            'content': 'Test content',
            'category': 1
        }

        self.client.login(username='staff', password='staff')
        response = self.client.post(reverse('post_update', kwargs={'pk': 1}),
                                    post_data)
        post = Post.objects.get(**post_data)

        self.assertRedirects(response, post.get_absolute_url())

    def test_post_delete_page_not_viewable_by_anonymous_user(self):
        post_delete_url = reverse('post_delete', kwargs={'pk': 1})
        login_url = reverse('admin:login') + '?next=' + post_delete_url

        response = self.client.get(reverse('post_delete', kwargs={'pk': 1}))
        self.assertRedirects(response, login_url)

    def test_post_delete_page_not_viewable_by_regular_user(self):
        post_delete_url = reverse('post_delete', kwargs={'pk': 1})
        login_url = reverse('admin:login') + '?next=' + post_delete_url

        self.client.login(username='joe', password='qwerty')
        response = self.client.get(reverse('post_delete', kwargs={'pk': 1}))
        self.assertRedirects(response, login_url)

    def test_post_delete_page_viewable_by_staff(self):
        post_delete_url = reverse('post_delete', kwargs={'pk': 1})

        self.client.login(username='staff', password='staff')
        response = self.client.get(post_delete_url)
        self.assertEqual(response.status_code, 200)

    def test_post_delete(self):
        self.client.login(username='staff', password='staff')
        response = self.client.post(reverse('post_delete', kwargs={'pk': 1}))

        self.assertEqual(Post.objects.filter(pk=1).count(), 0)
        self.assertRedirects(response, reverse('blog'))


class TestCategoriesReadViews(TestCase):

    """
    Тестуємо сторінки перегляду списку всіх категорій і сторінку
    перегляду категорії
    """

    fixtures = ['blog/fixtures/sample_blog_posts.json']

    def test_viewable_categories_list(self):
        response = self.client.get(reverse('category_list'))
        self.assertEqual(response.status_code, 200)

    def test_viewable_category_detail_main_page(self):
        response = self.client.get(reverse('category_detail',
                                           kwargs={'pk': 1}))
        self.assertEqual(response.status_code, 200)

    def test_viewable_category_detail_pages(self):
        page1 = self.client.get(reverse('category_detail_list',
                                        kwargs={'pk': 2, 'page': 1}))
        self.assertEqual(page1.status_code, 200)

        page2 = self.client.get(reverse('category_detail_list', kwargs={
            'pk': 2,
            'page': 2
        }))
        self.assertEqual(page2.status_code, 200)
