from django.test import TestCase, Client
from django.urls import reverse
from users.models import User
from ..models import Product
from .test_resources import datasets
from commons.validation_messages import (FORM_URL_INVALID, FORM_PRICE_INVALID_DECIMALS,
                                         FORM_PRICE_INVALID_DIGITS_AMOUNT, FORM_CURRENCY_INVALID,
                                         FORM_UNIQUE_USER_AND_PRODUCT_NAME_CONSTRAINT_VIOLATION, FORM_DATE_INVALID)


class ProductTestCases(TestCase):
    def setUp(self):
        User.objects.create_user('testuser1', '<EMAIL>', 'lubieplacki')
        self.client.login(email='<EMAIL>', password='<PASSWORD>')
        self.products_count = Product.objects.all().count
        self.datasets = datasets

    def test_if_valid_product_is_correctly_added_to_database(self):
        self.assertEqual(self.products_count(), 0)
        self.client.post(reverse('add_product'), datasets.get('full_valid_data'))
        self.assertEqual(self.products_count(), 1)

    def test_if_same_product_will_not_be_added_multiple_times(self):
        self.assertEqual(self.products_count(), 0)
        self.client.post(reverse('add_product'), datasets.get('full_valid_data'))
        self.assertEqual(self.products_count(), 1)
        for _ in range(10):
            response = self.client.post(reverse('add_product'), datasets.get('full_valid_data'))
        self.assertContains(response, FORM_UNIQUE_USER_AND_PRODUCT_NAME_CONSTRAINT_VIOLATION)
        self.assertEqual(self.products_count(), 1)

    def test_if_product_with_invalid_url_wont_be_created(self):
        self.assertEqual(self.products_count(), 0)
        response = self.client.post(reverse('add_product'), datasets.get('invalid_data_url'))
        self.assertContains(response, FORM_URL_INVALID)
        self.assertEqual(self.products_count(), 0)

    def test_if_product_with_invalid_price_wont_be_created(self):
        self.assertEqual(self.products_count(), 0)
        response = self.client.post(reverse('add_product'), datasets.get('invalid_data_price_too_many_decimals'))
        self.assertContains(response, FORM_PRICE_INVALID_DECIMALS)
        response = self.client.post(reverse('add_product'), datasets.get('invalid_data_price_too_many_digits'))
        self.assertContains(response, FORM_PRICE_INVALID_DIGITS_AMOUNT)
        self.assertEqual(self.products_count(), 0)

    def test_if_product_containing_valid_price_but_no_currency_wont_be_created(self):
        self.assertEqual(self.products_count(), 0)
        response = self.client.post(reverse('add_product'), datasets.get('invalid_data_price_with_no_currency'))
        self.assertContains(response, FORM_CURRENCY_INVALID)
        self.assertEqual(self.products_count(), 0)

    def test_if_product_with_invalid_dates_wont_be_created(self):
        self.assertEqual(self.products_count(), 0)
        response = self.client.post(reverse('add_product'), datasets.get('invalid_data_wrong_dates'))
        self.assertContains(response, FORM_DATE_INVALID)
        self.assertEqual(self.products_count(), 0)
