From a25063513244a563bf8afbdca78b8480b48bd569 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=AD=C3=B0ir=20Valberg=20Gu=C3=B0mundsson?= Date: Sun, 22 Apr 2018 08:31:10 +0200 Subject: [PATCH] Added the first tests to the project. Using factory_boy for great success. (#219) --- src/requirements/test.txt | 3 +++ src/shop/factories.py | 51 +++++++++++++++++++++++++++++++++++++++ src/shop/models.py | 2 +- src/shop/tests.py | 30 +++++++++++++++++++++++ src/utils/factories.py | 11 +++++++++ 5 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 src/requirements/test.txt create mode 100644 src/shop/factories.py create mode 100644 src/shop/tests.py create mode 100644 src/utils/factories.py diff --git a/src/requirements/test.txt b/src/requirements/test.txt new file mode 100644 index 00000000..a0232901 --- /dev/null +++ b/src/requirements/test.txt @@ -0,0 +1,3 @@ +-r dev.txt + +factory_boy==2.10.0 diff --git a/src/shop/factories.py b/src/shop/factories.py new file mode 100644 index 00000000..9b0c5e0c --- /dev/null +++ b/src/shop/factories.py @@ -0,0 +1,51 @@ +import factory + +from factory.django import DjangoModelFactory + +from django.utils import timezone + +from psycopg2.extras import DateTimeTZRange + +from utils.factories import UserFactory + + +class ProductCategoryFactory(DjangoModelFactory): + class Meta: + model = 'shop.ProductCategory' + + name = factory.Faker('word') + + +class ProductFactory(DjangoModelFactory): + class Meta: + model = 'shop.Product' + + name = factory.Faker('word') + slug = factory.Faker('word') + category = factory.SubFactory(ProductCategoryFactory) + description = factory.Faker('paragraph') + price = factory.Faker('pyint') + available_in = factory.LazyFunction( + lambda: + DateTimeTZRange( + lower=timezone.now(), + upper=timezone.now() + timezone.timedelta(31) + ) + ) + + +class OrderFactory(DjangoModelFactory): + class Meta: + model = 'shop.Order' + + user = factory.SubFactory(UserFactory) + + +class OrderProductRelationFactory(DjangoModelFactory): + class Meta: + model = 'shop.OrderProductRelation' + + product = factory.SubFactory(ProductFactory) + order = factory.SubFactory(OrderFactory) + quantity = 1 + handed_out = False diff --git a/src/shop/models.py b/src/shop/models.py index cca68232..a3ab1329 100644 --- a/src/shop/models.py +++ b/src/shop/models.py @@ -351,7 +351,7 @@ class Product(CreatedUpdatedModel, UUIDModel): """ now = timezone.now() time_available = now in self.available_in - stock_available = (self.stock_amount - self.left_in_stock()) > 0 + stock_available = self.left_in_stock() > 0 return time_available and stock_available def is_old(self): diff --git a/src/shop/tests.py b/src/shop/tests.py new file mode 100644 index 00000000..daca2dd5 --- /dev/null +++ b/src/shop/tests.py @@ -0,0 +1,30 @@ +from django.test import TestCase + +from .factories import ( + ProductFactory, + OrderFactory, + 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_available()) diff --git a/src/utils/factories.py b/src/utils/factories.py new file mode 100644 index 00000000..6cdf524e --- /dev/null +++ b/src/utils/factories.py @@ -0,0 +1,11 @@ +import factory +from factory.django import DjangoModelFactory + + +class UserFactory(DjangoModelFactory): + class Meta: + model = 'auth.User' + + username = factory.Faker('word') + email = factory.Faker('ascii_email') +