Skip to content

Commit

Permalink
Add Supplement Stack Composition Functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
jeffshek committed Sep 6, 2020
1 parent ac41cb5 commit 83cb334
Show file tree
Hide file tree
Showing 14 changed files with 392 additions and 17 deletions.
1 change: 1 addition & 0 deletions open/core/betterself/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ class SupplementStackCompositionFactory(DjangoModelFactory):

class Meta:
model = SupplementStackComposition
django_get_or_create = ["user", "supplement", "stack"]


class SupplementLogFactory(DjangoModelFactory):
Expand Down
3 changes: 3 additions & 0 deletions open/core/betterself/models/supplement_stack.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
from open.core.betterself.constants import BetterSelfResourceConstants
from open.utilities.fields import DEFAULT_MODELS_CHAR_FIELD
from open.utilities.models import BaseModelWithUserGeneratedContent


class SupplementStack(BaseModelWithUserGeneratedContent):
RESOURCE_NAME = BetterSelfResourceConstants.SUPPLEMENT_STACKS

name = DEFAULT_MODELS_CHAR_FIELD

class Meta:
Expand Down
3 changes: 3 additions & 0 deletions open/core/betterself/models/supplement_stack_composition.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
from django.db.models import DecimalField, ForeignKey, CASCADE

from open.core.betterself.constants import BetterSelfResourceConstants
from open.core.betterself.models.supplement import Supplement
from open.core.betterself.models.supplement_stack import SupplementStack
from open.utilities.models import BaseModelWithUserGeneratedContent


class SupplementStackComposition(BaseModelWithUserGeneratedContent):
RESOURCE_NAME = BetterSelfResourceConstants.SUPPLEMENT_STACK_COMPOSITIONS

supplement = ForeignKey(Supplement, on_delete=CASCADE)
stack = ForeignKey(SupplementStack, related_name="compositions", on_delete=CASCADE)
# by default, don't allow this to be blank, it doesn't make sense for a supplement stack
Expand Down
19 changes: 8 additions & 11 deletions open/core/betterself/serializers/supplement_log_serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@
from rest_framework.exceptions import ValidationError
from rest_framework.fields import (
UUIDField,
HiddenField,
CurrentUserDefault,
CharField,
DecimalField,
ChoiceField,
)
Expand Down Expand Up @@ -60,14 +57,14 @@ def get_display_name(self, instance):

class SupplementLogCreateUpdateSerializer(BaseCreateUpdateSerializer):
supplement_uuid = UUIDField(source="supplement.uuid")
user = HiddenField(default=CurrentUserDefault())
uuid = UUIDField(required=False, read_only=True)
notes = CharField(
default="",
trim_whitespace=True,
required=False,
allow_blank=True,
)
# user = HiddenField(default=CurrentUserDefault())
# uuid = UUIDField(required=False, read_only=True)
# notes = CharField(
# default="",
# trim_whitespace=True,
# required=False,
# allow_blank=True,
# )
quantity = DecimalField(decimal_places=4, max_digits=10, default=1)
source = ChoiceField(INPUT_SOURCES_TUPLES, default=WEB_INPUT_SOURCE)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
from django.core.exceptions import ValidationError
from rest_framework.fields import UUIDField, DecimalField

from open.core.betterself.models.supplement import Supplement
from open.core.betterself.models.supplement_stack import SupplementStack
from open.core.betterself.models.supplement_stack_composition import (
SupplementStackComposition,
)
from open.core.betterself.serializers.mixins import (
BaseCreateUpdateSerializer,
BaseModelReadSerializer,
)
from open.core.betterself.serializers.simple_generic_serializer import (
create_name_uuid_serializer,
)
from open.core.betterself.serializers.supplement_serializers import (
SimpleSupplementReadSerializer,
)
from open.core.betterself.serializers.validators import validate_model_uuid


class SupplementStackCompositionReadSerializer(BaseModelReadSerializer):
supplement = SimpleSupplementReadSerializer()
stack = create_name_uuid_serializer(SupplementStack)

class Meta:
model = SupplementStackComposition
fields = ("uuid", "supplement", "stack", "quantity", "display_name")


class SupplementStackCompositionCreateUpdateSerializer(BaseCreateUpdateSerializer):
supplement_uuid = UUIDField(source="supplement.uuid")
stack_uuid = UUIDField(source="stack.uuid")
quantity = DecimalField(decimal_places=4, max_digits=10, default=1)

class Meta:
model = SupplementStackComposition
fields = (
"user",
"uuid",
"notes",
"supplement_uuid",
"stack_uuid",
"quantity",
)

def validate_supplement_uuid(self, value):
user = self.context["request"].user
validate_model_uuid(Supplement, uuid=value, user=user)
return value

def validate_stack_uuid(self, value):
user = self.context["request"].user
validate_model_uuid(SupplementStack, uuid=value, user=user)
return value

def validate(self, validated_data):
user = self.context["request"].user
is_creating_instance = not self.instance

if validated_data.get("supplement"):
supplement_uuid = validated_data.pop("supplement")["uuid"]
supplement = Supplement.objects.get(uuid=supplement_uuid, user=user)
validated_data["supplement"] = supplement

if validated_data.get("stack"):
stack_uuid = validated_data.pop("stack")["uuid"]
stack = SupplementStack.objects.get(uuid=stack_uuid, user=user)
validated_data["stack"] = stack

# check for uniqueconstraints issues with creation
# for updates, probably be a little bit easier
# and skip for now
if is_creating_instance:
if self.Meta.model.objects.filter(
user=user,
stack=validated_data["stack"],
supplement=validated_data["supplement"],
).exists():
raise ValidationError(
"Fields supplement stack and supplement are not unique"
)

return validated_data
27 changes: 27 additions & 0 deletions open/core/betterself/serializers/supplement_stack_serializers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from open.core.betterself.models.supplement_stack import SupplementStack
from open.core.betterself.serializers.mixins import (
BaseCreateUpdateSerializer,
BaseModelReadSerializer,
)


class SupplementStackReadSerializer(BaseModelReadSerializer):
class Meta:
model = SupplementStack
fields = (
"uuid",
"name",
"notes",
"display_name",
)


class SupplementStackCreateUpdateSerializer(BaseCreateUpdateSerializer):
class Meta:
model = SupplementStack
fields = (
"uuid",
"name",
"user",
"notes",
)
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"""


class TestSupplementLogViews(BetterSelfResourceViewTestCaseMixin, TestCase):
class TestSupplementLogCreateViews(BetterSelfResourceViewTestCaseMixin, TestCase):
url_name = BetterSelfResourceConstants.SUPPLEMENT_LOGS
model_class_factory = SupplementLogFactory
model_class = SupplementLog
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
from django.contrib.auth import get_user_model
from test_plus import TestCase

from open.core.betterself.constants import BetterSelfResourceConstants
from open.core.betterself.factories import (
SupplementStackCompositionFactory,
SupplementStackFactory,
SupplementFactory,
)
from open.core.betterself.models.supplement_stack_composition import (
SupplementStackComposition,
)
from open.core.betterself.tests.mixins.resource_mixin import (
BetterSelfResourceViewTestCaseMixin,
GetTestsMixin,
DeleteTestsMixin,
)

User = get_user_model()

"""
python manage.py test --pattern="*test_supplement_stack_composition_views.py" --keepdb
"""


class SupplementStackCompositionCreateTestView(
BetterSelfResourceViewTestCaseMixin, TestCase
):
url_name = BetterSelfResourceConstants.SUPPLEMENT_STACK_COMPOSITIONS
model_class_factory = SupplementStackCompositionFactory
model_class = SupplementStackComposition

def test_create_view(self):
supplement = SupplementFactory(user=self.user_1)
stack = SupplementStackFactory(user=self.user_1)

supplement_uuid = str(supplement.uuid)
stack_uuid = str(stack.uuid)
quantity = 5

post_data = {
"supplement_uuid": supplement_uuid,
"stack_uuid": stack_uuid,
"quantity": quantity,
}

response = self.client_1.post(self.url, data=post_data)
self.assertEqual(response.status_code, 200)

def test_create_view_with_duplication_data(self):
supplement = SupplementFactory(user=self.user_1)
stack = SupplementStackFactory(user=self.user_1)

supplement_uuid = str(supplement.uuid)
stack_uuid = str(stack.uuid)
quantity = 5

post_data = {
"supplement_uuid": supplement_uuid,
"stack_uuid": stack_uuid,
"quantity": quantity,
}

response = self.client_1.post(self.url, data=post_data)
self.assertEqual(response.status_code, 200)

response = self.client_1.post(self.url, data=post_data)
self.assertEqual(response.status_code, 400)

expected_error_found = "non_field_errors" in response.data
self.assertTrue(expected_error_found)


class SupplementStackCompositionTestGetUpdateView(
BetterSelfResourceViewTestCaseMixin, GetTestsMixin, DeleteTestsMixin, TestCase
):
url_name = BetterSelfResourceConstants.SUPPLEMENT_STACK_COMPOSITIONS
model_class_factory = SupplementStackCompositionFactory
model_class = SupplementStackComposition

def test_update_quantity_in_supplement_stack_composition(self):
instance = SupplementStackCompositionFactory(user=self.user_1, quantity=10)

url = instance.get_update_url()
params = {"uuid": str(instance.uuid), "quantity": 5}

response = self.client_1.post(url, data=params)
data = response.data

self.assertEqual(response.status_code, 200, data)
self.assertEqual(float(data["quantity"]), 5)

def test_update_supplement_in_supplement_stack_composition(self):
instance = SupplementStackCompositionFactory(user=self.user_1, quantity=10)

supplement = SupplementFactory(user=self.user_1)

self.assertNotEqual(instance.supplement, supplement)

url = instance.get_update_url()
params = {"supplement_uuid": str(supplement.uuid), "quantity": 5}

response = self.client_1.post(url, data=params)
data = response.data

self.assertEqual(response.status_code, 200, data)
self.assertEqual(data["supplement"]["uuid"], str(supplement.uuid))
64 changes: 64 additions & 0 deletions open/core/betterself/tests/views/test_supplement_stack_views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
from django.contrib.auth import get_user_model
from test_plus import TestCase

from open.core.betterself.constants import BetterSelfResourceConstants
from open.core.betterself.factories import SupplementStackFactory
from open.core.betterself.models.supplement_stack import SupplementStack
from open.core.betterself.tests.mixins.resource_mixin import (
BetterSelfResourceViewTestCaseMixin,
GetTestsMixin,
DeleteTestsMixin,
)

User = get_user_model()

"""
python manage.py test --pattern="*test_supplement_stack_views.py" --keepdb
"""


class SupplementStackCreateTestView(BetterSelfResourceViewTestCaseMixin, TestCase):
url_name = BetterSelfResourceConstants.SUPPLEMENT_STACKS
model_class_factory = SupplementStackFactory
model_class = SupplementStack

def test_create_view(self):
silly_name = "MENTAL FOCUS POWER"
post_data = {"name": silly_name}

response = self.client_1.post(self.url, data=post_data)
self.assertEqual(response.status_code, 200)

data = response.data
self.assertEqual(data["name"], silly_name)


class SupplementStackTestGetUpdateView(
BetterSelfResourceViewTestCaseMixin, GetTestsMixin, DeleteTestsMixin, TestCase
):
url_name = BetterSelfResourceConstants.SUPPLEMENT_STACKS
model_class_factory = SupplementStackFactory
model_class = SupplementStack

def test_update_stack_name(self):
stack = SupplementStackFactory(user=self.user_1)
cool_name = "cool name"

params = {"name": cool_name}
url = stack.get_update_url()

response = self.client_1.post(url, data=params)
data = response.data

self.assertEqual(data["name"], cool_name)

def test_update_stack_name_no_access(self):
stack = SupplementStackFactory(user=self.user_1)
cool_name = "cool name"

params = {"name": cool_name}
url = stack.get_update_url()

# use a different client to make sure no data
response = self.client_2.post(url, data=params)
self.assertEqual(404, response.status_code)
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"""


class WellBeingLogTestView(BetterSelfResourceViewTestCaseMixin, TestCase):
class WellBeingLogCreateTestView(BetterSelfResourceViewTestCaseMixin, TestCase):
url_name = BetterSelfResourceConstants.WELL_BEING_LOGS
model_class_factory = WellBeingLogFactory
model_class = WellBeingLog
Expand Down
Loading

0 comments on commit 83cb334

Please sign in to comment.