Repository: saleor/saleor

Issue:
MenuItem should return linked object
### What I'm trying to achieve
At this moment MenuItem is able to return url, but not linked object, like category or collection. Without it, API consumer does not know if the returned url is static or generated, basing on linked object's properties.

### Describe a proposed solution
Change `MenuItem` signature to
```
type MenuItem {
  id: ID!
  menu: Menu!
  name: String!
  url: String
  category: Category
  collection: Collection
  page: Page
}
```



Discussion:

Resolving patch:
diff --git a/saleor/graphql/menu/types.py b/saleor/graphql/menu/types.py
--- a/saleor/graphql/menu/types.py
+++ b/saleor/graphql/menu/types.py
@@ -14,8 +14,9 @@ class Meta:
         filter_fields = {}
         model = models.Menu
 
-    def resolve_items(self, info):
-        return self.items.filter(level=0)
+    def resolve_items(self, info, **kwargs):
+        return self.items.filter(level=0).select_related(
+            'category', 'collection', 'page')
 
 
 class MenuItem(CountableDjangoObjectType):
@@ -25,7 +26,7 @@ class Meta:
         description = """Represents a single item of the related menu.
         Can store categories, collection or pages."""
         interfaces = [relay.Node]
-        only_fields = ['children', 'id', 'menu', 'name', 'url']
+        exclude_fields = ['sort_order', 'lft', 'rght', 'tree_id']
         filter_fields = {}
         model = models.MenuItem
 
diff --git a/saleor/graphql/product/types.py b/saleor/graphql/product/types.py
--- a/saleor/graphql/product/types.py
+++ b/saleor/graphql/product/types.py
@@ -208,7 +208,7 @@ class Meta:
         interfaces = [relay.Node]
         model = models.ProductType
 
-    def resolve_products(self, info):
+    def resolve_products(self, info, **kwargs):
         user = info.context.user
         return products_with_details(
             user=user).filter(product_type=self).distinct()


Test patch:
diff --git a/tests/api/test_menu.py b/tests/api/test_menu.py
--- a/tests/api/test_menu.py
+++ b/tests/api/test_menu.py
@@ -48,11 +48,11 @@ def test_menu_query(user_api_client, menu):
 def test_menus_query(user_api_client, menu, menu_item):
     query = """
     query menus($menu_name: String){
-        menus(query: $menu_name) {
+        menus(query: $menu_name, first: 1) {
             edges {
                 node {
                     name
-                    items {
+                    items(first: 1) {
                         edges {
                             node {
                                 name
@@ -93,6 +93,15 @@ def test_menu_items_query(user_api_client, menu_item, collection):
             children {
                 totalCount
             }
+            collection {
+                name
+            }
+            category {
+                id
+            }
+            page {
+                id
+            }
             url
         }
     }
@@ -109,6 +118,9 @@ def test_menu_items_query(user_api_client, menu_item, collection):
     assert data['name'] == menu_item.name
     assert data['url'] == menu_item.collection.get_absolute_url()
     assert data['children']['totalCount'] == menu_item.children.count()
+    assert data['collection']['name'] == collection.name
+    assert not data['category']
+    assert not data['page']
 
 
 def test_create_menu(admin_api_client, collection, category, page):
diff --git a/tests/api/test_product.py b/tests/api/test_product.py
--- a/tests/api/test_product.py
+++ b/tests/api/test_product.py
@@ -555,6 +555,13 @@ def test_product_type(user_api_client, product_type):
                 node {
                     id
                     name
+                    products(first: 1) {
+                        edges {
+                            node {
+                                id
+                            }
+                        }
+                    }
                 }
             }
         }