Repository: saleor/saleor

Issue:
Product attributes not visible on product details page
### What I'm trying to achieve
See product attributes values on the product details page.

### Steps to reproduce the problem
1. Fresh master clone
2. Add two shirts with various size and color attributes
3. Go to product details page
4. No attributes under product description

### What I expected to happen
An html table as shown in https://github.com/mirumee/saleor/blob/65e00b0d1497d329320b33c8bcdbe1fa8febfb9d/templates/product/details.html#L200-L207 showing the product attribute name and value.


Python-3.7.4
Gentoo Linux kv 5.0.13
Chromium-77.0.3865.35




Discussion:
I'm on newest master after running `populatedb` on fresh DB. Here is my product details page:
![image](https://user-images.githubusercontent.com/5421321/63835974-e662bd80-c978-11e9-8102-972216aecefe.png)

"Material: Cotton" is a product attribute in this case. If I understand correctly, it isn't rendered in your case?
> I'm on newest master after running `populatedb` on fresh DB. Here is my product details page:
> ![image](https://user-images.githubusercontent.com/5421321/63835974-e662bd80-c978-11e9-8102-972216aecefe.png)
> 
> "Material: Cotton" is a product attribute in this case. If I understand correctly, it isn't rendered in your case?

Try adding a new product with a custom attribute though. I only had issues with new products not existing ones.

Resolving patch:
diff --git a/saleor/dashboard/product/forms.py b/saleor/dashboard/product/forms.py
--- a/saleor/dashboard/product/forms.py
+++ b/saleor/dashboard/product/forms.py
@@ -527,7 +527,7 @@ def save(self):
 class AttributeForm(forms.ModelForm):
     class Meta:
         model = Attribute
-        exclude = ["input_type"]
+        fields = ["name", "slug"]
         labels = {
             "name": pgettext_lazy("Product display name", "Display name"),
             "slug": pgettext_lazy("Product internal name", "Internal name"),


Test patch:
diff --git a/tests/dashboard/test_product.py b/tests/dashboard/test_product.py
--- a/tests/dashboard/test_product.py
+++ b/tests/dashboard/test_product.py
@@ -878,7 +878,14 @@ def test_view_attribute_create(admin_client, color_attribute):
     response = admin_client.post(url, data, follow=True)
 
     assert response.status_code == 200
-    assert Attribute.objects.count() == 2, "An attribute should have been created"
+
+    created_attribute = Attribute.objects.filter(slug="test").first()
+    assert created_attribute is not None, "An attribute should have been created"
+
+    assert created_attribute.name == "test"
+    assert (
+        created_attribute.visible_in_storefront is True
+    ), "The default value should have been used"
 
 
 def test_view_attribute_create_not_valid(admin_client, color_attribute):
@@ -902,6 +909,30 @@ def test_view_attribute_edit(color_attribute, admin_client):
     color_attribute.refresh_from_db()
     assert color_attribute.name == "new_name"
     assert color_attribute.slug == "new_slug"
+    assert (
+        color_attribute.visible_in_storefront is True
+    ), "The default value should have been used"
+
+
+def test_view_attribute_edit_with_product_type(product, admin_client):
+    old_attribute_count = Attribute.objects.count()
+    product_attribute = (
+        product.product_type.product_attributes.first()
+    )  # type: Attribute
+    url = reverse("dashboard:attribute-update", kwargs={"pk": product_attribute.pk})
+    data = {"name": "new_name", "slug": "new_slug"}
+
+    response = admin_client.post(url, data, follow=True)
+
+    assert response.status_code == 200
+    assert (
+        Attribute.objects.count() == old_attribute_count
+    ), "A new attribute shouldn't have been created"
+
+    product_attribute.refresh_from_db()
+    assert (
+        product_attribute.product_types.count() == 1
+    ), "Product type shouldn't have been unassigned"
 
 
 def test_view_attribute_delete(admin_client, color_attribute):