Repository: plone/plone.restapi (language: python)

Issue:
Types service: Do not consider TypeSchemaContext as a valid context
The PR #1272 introduced the side-effect of getting the vocabulary in context (which is needed, given we do have contextual vocabularies), but for content created at the site root the vocabularies endpoints are broken: 
```
    "vocabulary": {
        "@id": "http://localhost:3000/dexterity-types/Document/@vocabularies/plone.app.vocabularies.SupportedContentLanguages"
    }
```

This happens because at the site root, instead of using the context, we use a TypeSchemaContext (/dexterity-types/<type-name>) which is not a "real" context.


Discussion / hints:

Fix patch:
diff --git a/news/1278.bugfix b/news/1278.bugfix
new file mode 100644
index 0000000000..22d64e8bef
--- /dev/null
+++ b/news/1278.bugfix
@@ -0,0 +1,2 @@
+Types service: Do not consider TypeSchemaContext as a valid context
+[@ericof]
diff --git a/src/plone/restapi/types/utils.py b/src/plone/restapi/types/utils.py
index 43b7cbe06f..bb50a372fa 100644
--- a/src/plone/restapi/types/utils.py
+++ b/src/plone/restapi/types/utils.py
@@ -300,7 +300,14 @@ def serializeSchema(schema):
 
 def get_info_for_type(context, request, name):
     """Get JSON info for the given portal type"""
-    schema = get_jsonschema_for_portal_type(name, context, request)
+    base_context = context
+
+    # If context is not a dexterity content, use site root to get
+    # the schema
+    if not IDexterityContent.providedBy(context):
+        base_context = getSite()
+
+    schema = get_jsonschema_for_portal_type(name, base_context, request)
 
     if not hasattr(context, "schema"):
         return schema


Test patch:
diff --git a/src/plone/restapi/tests/http-examples/translated_messages_types_folder.resp b/src/plone/restapi/tests/http-examples/translated_messages_types_folder.resp
index a2b07b64e3..f3b29f2112 100644
--- a/src/plone/restapi/tests/http-examples/translated_messages_types_folder.resp
+++ b/src/plone/restapi/tests/http-examples/translated_messages_types_folder.resp
@@ -87,7 +87,7 @@ Content-Type: application/json+schema
             "title": "Permitir comentarios",
             "type": "string",
             "vocabulary": {
-                "@id": "http://localhost:55001/plone/dexterity-types/Folder/@sources/allow_discussion"
+                "@id": "http://localhost:55001/plone/@sources/allow_discussion"
             }
         },
         "contributors": {
@@ -106,7 +106,7 @@ Content-Type: application/json+schema
             "uniqueItems": true,
             "widgetOptions": {
                 "vocabulary": {
-                    "@id": "http://localhost:55001/plone/dexterity-types/Folder/@vocabularies/plone.app.vocabularies.Users"
+                    "@id": "http://localhost:55001/plone/@vocabularies/plone.app.vocabularies.Users"
                 }
             }
         },
@@ -126,7 +126,7 @@ Content-Type: application/json+schema
             "uniqueItems": true,
             "widgetOptions": {
                 "vocabulary": {
-                    "@id": "http://localhost:55001/plone/dexterity-types/Folder/@vocabularies/plone.app.vocabularies.Users"
+                    "@id": "http://localhost:55001/plone/@vocabularies/plone.app.vocabularies.Users"
                 }
             }
         },
@@ -177,7 +177,7 @@ Content-Type: application/json+schema
             "title": "Idioma",
             "type": "string",
             "vocabulary": {
-                "@id": "http://localhost:55001/plone/dexterity-types/Folder/@vocabularies/plone.app.vocabularies.SupportedContentLanguages"
+                "@id": "http://localhost:55001/plone/@vocabularies/plone.app.vocabularies.SupportedContentLanguages"
             }
         },
         "nextPreviousEnabled": {
@@ -200,7 +200,7 @@ Content-Type: application/json+schema
                 "title": "Related",
                 "type": "string",
                 "vocabulary": {
-                    "@id": "http://localhost:55001/plone/dexterity-types/Folder/@vocabularies/plone.app.vocabularies.Catalog"
+                    "@id": "http://localhost:55001/plone/@vocabularies/plone.app.vocabularies.Catalog"
                 }
             },
             "title": "Contenido relacionado",
@@ -211,7 +211,7 @@ Content-Type: application/json+schema
                     "recentlyUsed": true
                 },
                 "vocabulary": {
-                    "@id": "http://localhost:55001/plone/dexterity-types/Folder/@vocabularies/plone.app.vocabularies.Catalog"
+                    "@id": "http://localhost:55001/plone/@vocabularies/plone.app.vocabularies.Catalog"
                 }
             }
         },
@@ -239,7 +239,7 @@ Content-Type: application/json+schema
             "uniqueItems": true,
             "widgetOptions": {
                 "vocabulary": {
-                    "@id": "http://localhost:55001/plone/dexterity-types/Folder/@vocabularies/plone.app.vocabularies.Keywords"
+                    "@id": "http://localhost:55001/plone/@vocabularies/plone.app.vocabularies.Keywords"
                 }
             }
         },
diff --git a/src/plone/restapi/tests/http-examples/types_document.resp b/src/plone/restapi/tests/http-examples/types_document.resp
index 5b395ff9e6..ddb61a6459 100644
--- a/src/plone/restapi/tests/http-examples/types_document.resp
+++ b/src/plone/restapi/tests/http-examples/types_document.resp
@@ -93,7 +93,7 @@ Content-Type: application/json+schema
             "title": "Allow discussion",
             "type": "string",
             "vocabulary": {
-                "@id": "http://localhost:55001/plone/dexterity-types/Document/@sources/allow_discussion"
+                "@id": "http://localhost:55001/plone/@sources/allow_discussion"
             }
         },
         "author_email": {
@@ -127,7 +127,7 @@ Content-Type: application/json+schema
             "uniqueItems": true,
             "widgetOptions": {
                 "vocabulary": {
-                    "@id": "http://localhost:55001/plone/dexterity-types/Document/@vocabularies/plone.app.vocabularies.Users"
+                    "@id": "http://localhost:55001/plone/@vocabularies/plone.app.vocabularies.Users"
                 }
             }
         },
@@ -147,7 +147,7 @@ Content-Type: application/json+schema
             "uniqueItems": true,
             "widgetOptions": {
                 "vocabulary": {
-                    "@id": "http://localhost:55001/plone/dexterity-types/Document/@vocabularies/plone.app.vocabularies.Users"
+                    "@id": "http://localhost:55001/plone/@vocabularies/plone.app.vocabularies.Users"
                 }
             }
         },
@@ -198,7 +198,7 @@ Content-Type: application/json+schema
             "title": "Language",
             "type": "string",
             "vocabulary": {
-                "@id": "http://localhost:55001/plone/dexterity-types/Document/@vocabularies/plone.app.vocabularies.SupportedContentLanguages"
+                "@id": "http://localhost:55001/plone/@vocabularies/plone.app.vocabularies.SupportedContentLanguages"
             }
         },
         "relatedItems": {
@@ -213,7 +213,7 @@ Content-Type: application/json+schema
                 "title": "Related",
                 "type": "string",
                 "vocabulary": {
-                    "@id": "http://localhost:55001/plone/dexterity-types/Document/@vocabularies/plone.app.vocabularies.Catalog"
+                    "@id": "http://localhost:55001/plone/@vocabularies/plone.app.vocabularies.Catalog"
                 }
             },
             "title": "Related Items",
@@ -224,7 +224,7 @@ Content-Type: application/json+schema
                     "recentlyUsed": true
                 },
                 "vocabulary": {
-                    "@id": "http://localhost:55001/plone/dexterity-types/Document/@vocabularies/plone.app.vocabularies.Catalog"
+                    "@id": "http://localhost:55001/plone/@vocabularies/plone.app.vocabularies.Catalog"
                 }
             }
         },
@@ -252,7 +252,7 @@ Content-Type: application/json+schema
             "uniqueItems": true,
             "widgetOptions": {
                 "vocabulary": {
-                    "@id": "http://localhost:55001/plone/dexterity-types/Document/@vocabularies/plone.app.vocabularies.Keywords"
+                    "@id": "http://localhost:55001/plone/@vocabularies/plone.app.vocabularies.Keywords"
                 }
             }
         },
diff --git a/src/plone/restapi/tests/http-examples/types_document_put.req b/src/plone/restapi/tests/http-examples/types_document_put.req
index dd2f11a5ef..4236762455 100644
--- a/src/plone/restapi/tests/http-examples/types_document_put.req
+++ b/src/plone/restapi/tests/http-examples/types_document_put.req
@@ -50,7 +50,7 @@ Content-Type: application/json
             "title": "Allow discussion",
             "type": "string",
             "vocabulary": {
-                "@id": "http://localhost:55001/plone/dexterity-types/Document/@sources/allow_discussion"
+                "@id": "http://localhost:55001/plone/@sources/allow_discussion"
             }
         },
         "author_email": {
@@ -96,7 +96,7 @@ Content-Type: application/json
             "uniqueItems": true,
             "widgetOptions": {
                 "vocabulary": {
-                    "@id": "http://localhost:55001/plone/dexterity-types/Document/@vocabularies/plone.app.vocabularies.Users"
+                    "@id": "http://localhost:55001/plone/@vocabularies/plone.app.vocabularies.Users"
                 }
             }
         },
@@ -116,7 +116,7 @@ Content-Type: application/json
             "uniqueItems": true,
             "widgetOptions": {
                 "vocabulary": {
-                    "@id": "http://localhost:55001/plone/dexterity-types/Document/@vocabularies/plone.app.vocabularies.Users"
+                    "@id": "http://localhost:55001/plone/@vocabularies/plone.app.vocabularies.Users"
                 }
             }
         },
@@ -167,7 +167,7 @@ Content-Type: application/json
             "title": "Language",
             "type": "string",
             "vocabulary": {
-                "@id": "http://localhost:55001/plone/dexterity-types/Document/@vocabularies/plone.app.vocabularies.SupportedContentLanguages"
+                "@id": "http://localhost:55001/plone/@vocabularies/plone.app.vocabularies.SupportedContentLanguages"
             }
         },
         "relatedItems": {
@@ -182,7 +182,7 @@ Content-Type: application/json
                 "title": "Related",
                 "type": "string",
                 "vocabulary": {
-                    "@id": "http://localhost:55001/plone/dexterity-types/Document/@vocabularies/plone.app.vocabularies.Catalog"
+                    "@id": "http://localhost:55001/plone/@vocabularies/plone.app.vocabularies.Catalog"
                 }
             },
             "title": "Related Items",
@@ -193,7 +193,7 @@ Content-Type: application/json
                     "recentlyUsed": true
                 },
                 "vocabulary": {
-                    "@id": "http://localhost:55001/plone/dexterity-types/Document/@vocabularies/plone.app.vocabularies.Catalog"
+                    "@id": "http://localhost:55001/plone/@vocabularies/plone.app.vocabularies.Catalog"
                 }
             }
         },
@@ -221,7 +221,7 @@ Content-Type: application/json
             "uniqueItems": true,
             "widgetOptions": {
                 "vocabulary": {
-                    "@id": "http://localhost:55001/plone/dexterity-types/Document/@vocabularies/plone.app.vocabularies.Keywords"
+                    "@id": "http://localhost:55001/plone/@vocabularies/plone.app.vocabularies.Keywords"
                 }
             }
         },