forked from saleor/saleor
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtest_product_attributes.py
139 lines (107 loc) · 5.02 KB
/
test_product_attributes.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
from unittest.mock import MagicMock, Mock
import pytest
from prices import Money
from saleor.product import AttributeInputType
from saleor.product.models import AttributeValue, Product, ProductType, ProductVariant
from saleor.product.tasks import _update_variants_names
from saleor.product.utils.attributes import (
associate_attribute_values_to_instance,
generate_name_for_variant,
)
@pytest.fixture()
def variant_with_no_attributes(category):
"""Create a variant having no attributes, the same for the parent product."""
product_type = ProductType.objects.create(
name="Test product type", has_variants=True, is_shipping_required=True
)
product = Product.objects.create(
name="Test product",
price=Money(10, "USD"),
product_type=product_type,
category=category,
)
variant = ProductVariant.objects.create(product=product, sku="123")
return variant
def test_generate_name_for_variant(
variant_with_no_attributes, color_attribute_without_values, size_attribute
):
"""Test the name generation from a given variant containing multiple attributes and
different input types (dropdown and multiselect).
"""
variant = variant_with_no_attributes
color_attribute = color_attribute_without_values
# Assign the attributes to the product type
variant.product.product_type.variant_attributes.set(
(color_attribute, size_attribute)
)
# Set the color attribute to a multi-value attribute
color_attribute.input_type = AttributeInputType.MULTISELECT
color_attribute.save(update_fields=["input_type"])
# Create colors
colors = AttributeValue.objects.bulk_create(
[
AttributeValue(attribute=color_attribute, name="Yellow", slug="yellow"),
AttributeValue(attribute=color_attribute, name="Blue", slug="blue"),
AttributeValue(attribute=color_attribute, name="Red", slug="red"),
]
)
# Retrieve the size attribute value "Big"
size = size_attribute.values.get(slug="big")
# Associate the colors and size to variant attributes
associate_attribute_values_to_instance(variant, color_attribute, *tuple(colors))
associate_attribute_values_to_instance(variant, size_attribute, size)
# Generate the variant name from the attributes
name = generate_name_for_variant(variant)
assert name == "Yellow, Blue, Red / Big"
def test_generate_name_from_values_empty(variant_with_no_attributes):
"""Ensure generate a variant name from a variant without any attributes assigned
returns an empty string."""
name = generate_name_for_variant(variant_with_no_attributes)
assert name == ""
def test_product_type_update_changes_variant_name(product):
new_name = "test_name"
product_variant = product.variants.first()
assert not product_variant.name == new_name
attribute = product.product_type.variant_attributes.first()
attribute_value = attribute.values.first()
attribute_value.name = new_name
attribute_value.save()
_update_variants_names(product.product_type, [attribute])
product_variant.refresh_from_db()
assert product_variant.name == new_name
def test_update_variants_changed_does_nothing_with_no_attributes():
product_type = MagicMock(spec=ProductType)
product_type.variant_attributes.all = Mock(return_value=[])
saved_attributes = []
# FIXME: This method no longer returns any value
assert _update_variants_names(product_type, saved_attributes) is None
def test_associate_attribute_to_non_product_instance(color_attribute):
instance = ProductType()
attribute = color_attribute
value = color_attribute.values.first()
with pytest.raises(AssertionError) as exc:
associate_attribute_values_to_instance(instance, attribute, value) # noqa
assert exc.value.args == ("ProductType is unsupported",)
def test_associate_attribute_to_product_instance_from_different_attribute(
product, color_attribute, size_attribute
):
"""Ensure an assertion error is raised when one tries to associate attribute values
to an object that don't belong to the supplied attribute.
"""
instance = product
attribute = color_attribute
value = size_attribute.values.first()
with pytest.raises(AssertionError) as exc:
associate_attribute_values_to_instance(instance, attribute, value)
assert exc.value.args == ("Some values are not from the provided attribute.",)
def test_associate_attribute_to_product_instance_without_values(product):
"""Ensure clearing the values from a product is properly working."""
old_assignment = product.attributes.first()
assert old_assignment is not None, "The product doesn't have attribute-values"
assert old_assignment.values.count() == 1
attribute = old_assignment.attribute
# Clear the values
new_assignment = associate_attribute_values_to_instance(product, attribute)
# Ensure the values were cleared and no new assignment entry was created
assert new_assignment.pk == old_assignment.pk
assert new_assignment.values.count() == 0