How do I fix this errors when running my tests

76 views Asked by At
from django.conf import settings
from django.utils.functional import cached_property

from regulus_oscar.apps.catalogue.abstract_models import AbstractProduct


class Product(AbstractProduct):
    def __str__(self):
        """
        Appends the variant-identifier product attribute values to the string
        representation of child products, for use in multiple places, including
        on the front end and dashboard, and in emails to customers and the
        merchant.
        """
        if self.is_child and self.variant_attribute_summaries:
            # The parent "__str__" method appends a summary of all the product
            # attribute values, whereas we only want to include a summary of the
            # variant-identifier ones
            return f"{ self.title if self.title else self.parent.title } ({ self.variant_attribute_summaries })"
        else:
            return super().__str__()

    def get_title(self):
        """
        Appends the variant-identifier product attribute values to the title of
        child products, for use in multiple places, including on the front end
        and dashboard, and in emails to customers and the merchant.
        """
        title = super().get_title()
        if self.is_child and self.variant_attribute_summaries:
            title = f"{ title } ({ self.variant_attribute_summaries })"
        return title

    get_title.short_description = "Title"

    @cached_property
    def variant_attribute_summaries(self):
        """
        Returns a string of a product's variant-identifier ("Colour" and "Size")
        product attribute values.
        """
        return ", ".join(
            [
                product_attribute_value.summary()
                for product_attribute_value in self.get_attribute_values().filter(
                    attribute__name__in=settings.NSH_VARIANT_PRODUCT_ATTRIBUTE_NAMES
                )
            ]
       )

from regulus_oscar.apps.catalogue.models import *  # noqa isort:skip

Above is my models.py file and everything works as expected on the front-end side of things however when I run the tests below I have some errors and I believe they are being caused by the @cached_property. How can I fix this issue for testing purposes and have it deployed to production without issues? I need the @cached_property to avoid calling the database every time since its a very large project and this will cause the site to slow down significantly

import pytest
from regulus_oscar.test.factories import (
    ProductAttributeFactory,
    ProductAttributeValueFactory,
    ProductClassFactory,
    ProductFactory,
)

@pytest.mark.django_db
def test_product_get_title_without_variant_attribute_summaries_for_child_products(settings):
    settings.NSH_VARIANT_PRODUCT_ATTRIBUTE_NAMES = [
        "Colour",
        "Size",
    ]
    product_class = ProductClassFactory(name="Foo")
    parent_product = ProductFactory(structure="parent", product_class=product_class)
    child_product = ProductFactory(structure="child", parent=parent_product, title = 'Foobar')
    assert child_product.get_title() == 'Foobar'

@pytest.mark.django_db
def test_variant_attribute_summaries_returns_string_when_variant_attributes_exist_for_child_products(settings):
    settings.NSH_VARIANT_PRODUCT_ATTRIBUTE_NAMES = [
        "Colour",
        "Size",
    ]
    product_class = ProductClassFactory(name="Foo")
    colour_attribute = ProductAttributeFactory(product_class=product_class, name="Colour", code="colour", type="color")
    size_attribute = ProductAttributeFactory(product_class=product_class, name="Size", code="size", type="text")
    parent_product = ProductFactory(structure="parent", product_class=product_class)
    child_product = ProductFactory(structure="child", parent=parent_product, title='Foobar')
    red = ProductAttributeValueFactory(attribute=colour_attribute, product=child_product, value_text="#ff0000")
    small = ProductAttributeValueFactory(attribute=size_attribute, product=child_product, value_text="Small")
    attribute_summary = child_product.variant_attribute_summaries
    assert attribute_summary == 'Colour: #ff0000, Size: Small'

@pytest.mark.django_db
def test_variant_attribute_summaries_returns_empty_string_when_variant_attributes_do_not_exist_for_child_product(settings):
    settings.NSH_VARIANT_PRODUCT_ATTRIBUTE_NAMES = [
        "Colour",
        "Size",
    ]
    product_class = ProductClassFactory(name="Foo")
    parent_product = ProductFactory(structure="parent", product_class=product_class)
    child_product = ProductFactory(structure="child", parent=parent_product)
    attribute_summary = child_product.variant_attribute_summaries
    assert attribute_summary == ''

@pytest.mark.django_db
def test_variant_attribute_summaries_returns_string_when_variant_attributes_exist_for_parent_products(settings):
    settings.NSH_VARIANT_PRODUCT_ATTRIBUTE_NAMES = [
        "Colour",
        "Size",
    ]
    product_class = ProductClassFactory(name="Foo")
    colour_attribute = ProductAttributeFactory(product_class=product_class, name="Colour", code="colour", type="color")
    size_attribute = ProductAttributeFactory(product_class=product_class, name="Size", code="size", type="text")
    parent_product = ProductFactory(structure="parent", product_class=product_class, title="Parent Product")
    red = ProductAttributeValueFactory(attribute=colour_attribute, product=parent_product, value_text="#ff0000")
    small = ProductAttributeValueFactory(attribute=size_attribute, product=parent_product, value_text="Small")
    assert parent_product.variant_attribute_summaries == 'Colour: #ff0000, Size: Small'

@pytest.mark.django_db
def test_variant_attribute_summaries_returns_empty_string_when_variant_attributes_do_not_exist_for_parent_products(settings):
    settings.NSH_VARIANT_PRODUCT_ATTRIBUTE_NAMES = [
        "Colour",
        "Size",
    ]
    product_class = ProductClassFactory(name="Foo")
    parent_product = ProductFactory(structure="parent", product_class=product_class)
    attribute_summary = parent_product.variant_attribute_summaries
    assert attribute_summary == ''

@pytest.mark.django_db
def test_product_get_title_without_variant_attribute_summaries_for_parent_products(settings):
    settings.NSH_VARIANT_PRODUCT_ATTRIBUTE_NAMES = [
        "Colour",
        "Size",
    ]
    product_class = ProductClassFactory(name="Foo")
    parent_product = ProductFactory(structure="parent", product_class=product_class, title = 'Foobar')
    assert parent_product.get_title() == 'Foobar'

@pytest.mark.django_db
def test_str__for_product_without_variant_attribute_summaries_for_parent_products(settings):
    settings.NSH_VARIANT_PRODUCT_ATTRIBUTE_NAMES = [
        "Colour",
        "Size",
    ]
    product_class = ProductClassFactory(name="Foo")
    colour_attribute = ProductAttributeFactory(product_class=product_class, name="Colour", code="colour", type="color")
    size_attribute = ProductAttributeFactory(product_class=product_class, name="Size", code="size", type="text")
    parent_product = ProductFactory(structure="parent", product_class=product_class, title="Parent Product")
    red = ProductAttributeValueFactory(attribute=colour_attribute, product=parent_product, value_text="#ff0000")
    small = ProductAttributeValueFactory(attribute=size_attribute, product=parent_product, value_text="Small")
    assert str(parent_product) == 'Parent Product'

@pytest.mark.django_db
def test_get_title_returns_string_when_variant_attributes_exist_for_child_products(settings):
    settings.NSH_VARIANT_PRODUCT_ATTRIBUTE_NAMES = [
        "Colour",
        "Size",
    ]
    product_class = ProductClassFactory(name="Foo")
    colour_attribute = ProductAttributeFactory(product_class=product_class, name="Colour", code="colour", type="color")
    size_attribute = ProductAttributeFactory(product_class=product_class, name="Size", code="size", type="text")
    parent_product = ProductFactory(structure="parent", product_class=product_class)
    child_product = ProductFactory(structure="child", parent=parent_product, title = 'Foobar')
    red = ProductAttributeValueFactory(attribute=colour_attribute, product=child_product, value_text="#ff0000")
    small = ProductAttributeValueFactory(attribute=size_attribute, product=child_product, value_text="Small")
    assert child_product.get_title() == 'Foobar (Colour: #ff0000, Size: Small)'

@pytest.mark.django_db
def test_settings_variant_attribute_names_can_be_overriden_trough_setting(settings):
    list_of_settings = settings.NSH_VARIANT_PRODUCT_ATTRIBUTE_NAMES = [
        "Colour",
        "Size",
    ]
    list_of_settings[0] = 'testColour'
    list_of_settings[1] = 'testSize'
    product_class = ProductClassFactory(name="Foo")
    colour_attribute = ProductAttributeFactory(product_class=product_class, name="testColour", code="colour", type="color")
    size_attribute = ProductAttributeFactory(product_class=product_class, name="testSize", code="size", type="text")
    parent_product = ProductFactory(structure="parent", product_class=product_class, title="Parent Product")
    red = ProductAttributeValueFactory(attribute=colour_attribute, product=parent_product, value_text="#ff0000")
    small = ProductAttributeValueFactory(attribute=size_attribute, product=parent_product, value_text="Small")
    assert parent_product.variant_attribute_summaries == 'testColour: #ff0000, testSize: Small'

Below are the errors I get when I run the tests

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
=========================================================================================== short test summary info ===========================================================================================
FAILED tests/catalogue/test_models.py::test_variant_attribute_summaries_returns_string_when_variant_attributes_exist_for_child_products - AssertionError: assert '' == 'Colour: #ff0000, Size: Small'
FAILED tests/catalogue/test_models.py::test_get_title_returns_string_when_variant_attributes_exist_for_child_products - AssertionError: assert 'Foobar' == 'Foobar (Colo... Size: Small)'
FAILED tests/catalogue/test_models.py::test_settings_variant_attribute_names_can_be_overriden_trough_setting - AssertionError: assert '' == 'testColour: ...stSize: Small'

The code works as expected in the front-end and when the cached-property is removed it works well but I need that property for production purposes, what can I do to allow the tests to run without issues from this? Thank you.

1

There are 1 answers

6
Marco On

Change _variant_attribute_summaries to variant_attribute_summaries in your tests as you defined it without a leading underscore in your models...

...
def variant_attribute_summaries(self):
...