from django.test import TestCase
from django.utils import timezone

from psycopg2.extras import DateTimeTZRange

from .factories import (
    ProductFactory,
    OrderProductRelationFactory,
)


class ProductAvailabilityTest(TestCase):
    """ Test logic about availability of products. """

    def test_product_available_by_stock(self):
        """ If no orders have been made, the product is still available. """
        product = ProductFactory(stock_amount=10)
        self.assertEqual(product.left_in_stock, 10)
        self.assertTrue(product.is_available())

    def test_product_not_available_by_stock(self):
        """ If max orders have been made, the product is NOT available. """
        product = ProductFactory(stock_amount=2)

        for i in range(2):
            opr = OrderProductRelationFactory(product=product)
            order = opr.order
            order.paid = True
            order.save()

        self.assertEqual(product.left_in_stock, 0)
        self.assertFalse(product.is_stock_available)
        self.assertFalse(product.is_available())

    def test_product_available_by_time(self):
        """ The product is available if now is in the right timeframe. """
        product = ProductFactory()
        # The factory defines the timeframe as now and 31 days forward.
        self.assertTrue(product.is_time_available)
        self.assertTrue(product.is_available())

    def test_product_not_available_by_time(self):
        """ The product is not available if now is outside the timeframe. """
        available_in = DateTimeTZRange(
            lower=timezone.now() - timezone.timedelta(5),
            upper=timezone.now() - timezone.timedelta(1)
        )
        product = ProductFactory(available_in=available_in)
        # The factory defines the timeframe as now and 31 days forward.
        self.assertFalse(product.is_time_available)
        self.assertFalse(product.is_available())

    def test_product_is_not_available_yet(self):
        """ The product is not available because we are before lower bound. """
        available_in = DateTimeTZRange(
            lower=timezone.now() + timezone.timedelta(5)
        )
        product = ProductFactory(available_in=available_in)
        # Make sure there is no upper - just in case.
        self.assertEqual(product.available_in.upper, None)
        # The factory defines the timeframe as now and 31 days forward.
        self.assertFalse(product.is_time_available)
        self.assertFalse(product.is_available())

    def test_product_is_available_from_now_on(self):
        """ The product is available because we are after lower bound. """
        available_in = DateTimeTZRange(
            lower=timezone.now() - timezone.timedelta(1)
        )
        product = ProductFactory(available_in=available_in)
        # Make sure there is no upper - just in case.
        self.assertEqual(product.available_in.upper, None)
        # The factory defines the timeframe as now and 31 days forward.
        self.assertTrue(product.is_time_available)
        self.assertTrue(product.is_available())

8215fce3468d5ececf97f6f54f57f22beda98a83
<mask token>


class ProductAvailabilityTest(TestCase):
    <mask token>
    <mask token>
    <mask token>

    def test_product_available_by_time(self):
        """ The product is available if now is in the right timeframe. """
        product = ProductFactory()
        self.assertTrue(product.is_time_available)
        self.assertTrue(product.is_available())
    <mask token>
    <mask token>

    def test_product_is_available_from_now_on(self):
        """ The product is available because we are after lower bound. """
        available_in = DateTimeTZRange(lower=timezone.now() - timezone.
            timedelta(1))
        product = ProductFactory(available_in=available_in)
        self.assertEqual(product.available_in.upper, None)
        self.assertTrue(product.is_time_available)
        self.assertTrue(product.is_available())

<mask token>


class ProductAvailabilityTest(TestCase):
    <mask token>

    def test_product_available_by_stock(self):
        """ If no orders have been made, the product is still available. """
        product = ProductFactory(stock_amount=10)
        self.assertEqual(product.left_in_stock, 10)
        self.assertTrue(product.is_available())

    def test_product_not_available_by_stock(self):
        """ If max orders have been made, the product is NOT available. """
        product = ProductFactory(stock_amount=2)
        for i in range(2):
            opr = OrderProductRelationFactory(product=product)
            order = opr.order
            order.paid = True
            order.save()
        self.assertEqual(product.left_in_stock, 0)
        self.assertFalse(product.is_stock_available)
        self.assertFalse(product.is_available())

    def test_product_available_by_time(self):
        """ The product is available if now is in the right timeframe. """
        product = ProductFactory()
        self.assertTrue(product.is_time_available)
        self.assertTrue(product.is_available())

    def test_product_not_available_by_time(self):
        """ The product is not available if now is outside the timeframe. """
        available_in = DateTimeTZRange(lower=timezone.now() - timezone.
            timedelta(5), upper=timezone.now() - timezone.timedelta(1))
        product = ProductFactory(available_in=available_in)
        self.assertFalse(product.is_time_available)
        self.assertFalse(product.is_available())

    def test_product_is_not_available_yet(self):
        """ The product is not available because we are before lower bound. """
        available_in = DateTimeTZRange(lower=timezone.now() + timezone.
            timedelta(5))
        product = ProductFactory(available_in=available_in)
        self.assertEqual(product.available_in.upper, None)
        self.assertFalse(product.is_time_available)
        self.assertFalse(product.is_available())

    def test_product_is_available_from_now_on(self):
        """ The product is available because we are after lower bound. """
        available_in = DateTimeTZRange(lower=timezone.now() - timezone.
            timedelta(1))
        product = ProductFactory(available_in=available_in)
        self.assertEqual(product.available_in.upper, None)
        self.assertTrue(product.is_time_available)
        self.assertTrue(product.is_available())

<mask token>


class ProductAvailabilityTest(TestCase):
    """ Test logic about availability of products. """

    def test_product_available_by_stock(self):
        """ If no orders have been made, the product is still available. """
        product = ProductFactory(stock_amount=10)
        self.assertEqual(product.left_in_stock, 10)
        self.assertTrue(product.is_available())

    def test_product_not_available_by_stock(self):
        """ If max orders have been made, the product is NOT available. """
        product = ProductFactory(stock_amount=2)
        for i in range(2):
            opr = OrderProductRelationFactory(product=product)
            order = opr.order
            order.paid = True
            order.save()
        self.assertEqual(product.left_in_stock, 0)
        self.assertFalse(product.is_stock_available)
        self.assertFalse(product.is_available())

    def test_product_available_by_time(self):
        """ The product is available if now is in the right timeframe. """
        product = ProductFactory()
        self.assertTrue(product.is_time_available)
        self.assertTrue(product.is_available())

    def test_product_not_available_by_time(self):
        """ The product is not available if now is outside the timeframe. """
        available_in = DateTimeTZRange(lower=timezone.now() - timezone.
            timedelta(5), upper=timezone.now() - timezone.timedelta(1))
        product = ProductFactory(available_in=available_in)
        self.assertFalse(product.is_time_available)
        self.assertFalse(product.is_available())

    def test_product_is_not_available_yet(self):
        """ The product is not available because we are before lower bound. """
        available_in = DateTimeTZRange(lower=timezone.now() + timezone.
            timedelta(5))
        product = ProductFactory(available_in=available_in)
        self.assertEqual(product.available_in.upper, None)
        self.assertFalse(product.is_time_available)
        self.assertFalse(product.is_available())

    def test_product_is_available_from_now_on(self):
        """ The product is available because we are after lower bound. """
        available_in = DateTimeTZRange(lower=timezone.now() - timezone.
            timedelta(1))
        product = ProductFactory(available_in=available_in)
        self.assertEqual(product.available_in.upper, None)
        self.assertTrue(product.is_time_available)
        self.assertTrue(product.is_available())

from django.test import TestCase
from django.utils import timezone
from psycopg2.extras import DateTimeTZRange
from .factories import ProductFactory, OrderProductRelationFactory


class ProductAvailabilityTest(TestCase):
    """ Test logic about availability of products. """

    def test_product_available_by_stock(self):
        """ If no orders have been made, the product is still available. """
        product = ProductFactory(stock_amount=10)
        self.assertEqual(product.left_in_stock, 10)
        self.assertTrue(product.is_available())

    def test_product_not_available_by_stock(self):
        """ If max orders have been made, the product is NOT available. """
        product = ProductFactory(stock_amount=2)
        for i in range(2):
            opr = OrderProductRelationFactory(product=product)
            order = opr.order
            order.paid = True
            order.save()
        self.assertEqual(product.left_in_stock, 0)
        self.assertFalse(product.is_stock_available)
        self.assertFalse(product.is_available())

    def test_product_available_by_time(self):
        """ The product is available if now is in the right timeframe. """
        product = ProductFactory()
        self.assertTrue(product.is_time_available)
        self.assertTrue(product.is_available())

    def test_product_not_available_by_time(self):
        """ The product is not available if now is outside the timeframe. """
        available_in = DateTimeTZRange(lower=timezone.now() - timezone.
            timedelta(5), upper=timezone.now() - timezone.timedelta(1))
        product = ProductFactory(available_in=available_in)
        self.assertFalse(product.is_time_available)
        self.assertFalse(product.is_available())

    def test_product_is_not_available_yet(self):
        """ The product is not available because we are before lower bound. """
        available_in = DateTimeTZRange(lower=timezone.now() + timezone.
            timedelta(5))
        product = ProductFactory(available_in=available_in)
        self.assertEqual(product.available_in.upper, None)
        self.assertFalse(product.is_time_available)
        self.assertFalse(product.is_available())

    def test_product_is_available_from_now_on(self):
        """ The product is available because we are after lower bound. """
        available_in = DateTimeTZRange(lower=timezone.now() - timezone.
            timedelta(1))
        product = ProductFactory(available_in=available_in)
        self.assertEqual(product.available_in.upper, None)
        self.assertTrue(product.is_time_available)
        self.assertTrue(product.is_available())

from django.test import TestCase
from django.utils import timezone

from psycopg2.extras import DateTimeTZRange

from .factories import (
    ProductFactory,
    OrderProductRelationFactory,
)


class ProductAvailabilityTest(TestCase):
    """ Test logic about availability of products. """

    def test_product_available_by_stock(self):
        """ If no orders have been made, the product is still available. """
        product = ProductFactory(stock_amount=10)
        self.assertEqual(product.left_in_stock, 10)
        self.assertTrue(product.is_available())

    def test_product_not_available_by_stock(self):
        """ If max orders have been made, the product is NOT available. """
        product = ProductFactory(stock_amount=2)

        for i in range(2):
            opr = OrderProductRelationFactory(product=product)
            order = opr.order
            order.paid = True
            order.save()

        self.assertEqual(product.left_in_stock, 0)
        self.assertFalse(product.is_stock_available)
        self.assertFalse(product.is_available())

    def test_product_available_by_time(self):
        """ The product is available if now is in the right timeframe. """
        product = ProductFactory()
        # The factory defines the timeframe as now and 31 days forward.
        self.assertTrue(product.is_time_available)
        self.assertTrue(product.is_available())

    def test_product_not_available_by_time(self):
        """ The product is not available if now is outside the timeframe. """
        available_in = DateTimeTZRange(
            lower=timezone.now() - timezone.timedelta(5),
            upper=timezone.now() - timezone.timedelta(1)
        )
        product = ProductFactory(available_in=available_in)
        # The factory defines the timeframe as now and 31 days forward.
        self.assertFalse(product.is_time_available)
        self.assertFalse(product.is_available())

    def test_product_is_not_available_yet(self):
        """ The product is not available because we are before lower bound. """
        available_in = DateTimeTZRange(
            lower=timezone.now() + timezone.timedelta(5)
        )
        product = ProductFactory(available_in=available_in)
        # Make sure there is no upper - just in case.
        self.assertEqual(product.available_in.upper, None)
        # The factory defines the timeframe as now and 31 days forward.
        self.assertFalse(product.is_time_available)
        self.assertFalse(product.is_available())

    def test_product_is_available_from_now_on(self):
        """ The product is available because we are after lower bound. """
        available_in = DateTimeTZRange(
            lower=timezone.now() - timezone.timedelta(1)
        )
        product = ProductFactory(available_in=available_in)
        # Make sure there is no upper - just in case.
        self.assertEqual(product.available_in.upper, None)
        # The factory defines the timeframe as now and 31 days forward.
        self.assertTrue(product.is_time_available)
        self.assertTrue(product.is_available())
