From 3b004a264e6d874a6b343fabeaef530322fbe20f Mon Sep 17 00:00:00 2001 From: Jeff Zellman Date: Wed, 14 Aug 2019 18:30:23 -0400 Subject: [PATCH] feat: support relationships that are named "type" In order to handle this, the json:api attribute "type" is provided in the deserialized doc as "$type". --- README.rst | 4 +-- json_api_doc/deserialization.py | 8 ++++-- tests/test_relationships.py | 51 +++++++++++++++++++++++++++------ tests/test_simple.py | 8 +++--- 4 files changed, 54 insertions(+), 17 deletions(-) diff --git a/README.rst b/README.rst index cf7cb19..8145dfd 100644 --- a/README.rst +++ b/README.rst @@ -67,14 +67,14 @@ The simplified version will be: [ { - "type": "articles", + "$type": "articles", "id": "1", "title": "JSON API paints my bikeshed!", "body": "The shortest article. Ever.", "created": "2015-05-22T14:56:29.000Z", "updated": "2015-05-22T14:56:28.000Z", "author": { - "type": "people", + "$type": "people", "id": "42", "name": "John", "age": 80, diff --git a/json_api_doc/deserialization.py b/json_api_doc/deserialization.py index fd11318..f667d5f 100644 --- a/json_api_doc/deserialization.py +++ b/json_api_doc/deserialization.py @@ -34,7 +34,7 @@ def _resolve(data, included, resolved): for key, value in data.items(): if isinstance(value, tuple): id = { - "type": value[0], + "$type": value[0], "id": value[1] } resolved_item = included.get(value, id) @@ -52,7 +52,7 @@ def _resolve(data, included, resolved): for item in value: if isinstance(item, tuple): id = { - "type": item[0], + "$type": item[0], "id": item[1] } resolved_item = included.get(item, id) @@ -73,13 +73,15 @@ def _resolve(data, included, resolved): def _parse_included(included): result = {} for include in included: - result[(include["type"], include["id"])] = _flat(include) + result[(include["$type"], include["id"])] = _flat(include) return result def _flat(obj): + obj['$type'] = obj.pop('type') obj.pop("links", None) obj.update(obj.pop("attributes", {})) + if "relationships" in obj: for relationship, item in obj.pop("relationships").items(): data = item.get("data") diff --git a/tests/test_relationships.py b/tests/test_relationships.py index 183f4bc..efd36af 100644 --- a/tests/test_relationships.py +++ b/tests/test_relationships.py @@ -66,7 +66,7 @@ def test_parse_included(): }] assert json_api_doc._parse_included(data) == { ("people", "9"): { - "type": "people", + "$type": "people", "id": "9", "first-name": "Bob", "last-name": "Doe", @@ -101,7 +101,7 @@ def test_resolve_missing(): doc = json_api_doc._resolve(data, included, set()) assert doc == { "title": "Article 1", - "author": {"type": "people", "id": "9"} + "author": {"$type": "people", "id": "9"} } @@ -145,8 +145,8 @@ def test_resolve_list_missing_items(): assert doc == { "title": "Article 1", "authors": [ - {"id": "9", "type": "people"}, - {"id": "10", "type": "people"} + {"id": "9", "$type": "people"}, + {"id": "10", "$type": "people"} ] } @@ -204,7 +204,7 @@ def test_resolve_loop(): "name": "Jean", "father": { "name": "Luc", - "son": {"type": "people", "id": "1"} + "son": {"$type": "people", "id": "1"} } } } @@ -235,11 +235,11 @@ def test_simple_relationships(): } doc = json_api_doc.parse(response) assert doc == { - "type": "article", + "$type": "article", "id": "1", "title": "Article 1", "author": { - "type": "people", + "$type": "people", "id": "9", "first-name": "Bob", "last-name": "Doe" @@ -266,7 +266,7 @@ def test_linked_relationship(): } doc = json_api_doc.parse(response) assert doc == { - "type": "article", + "$type": "article", "id": "1", "title": "Article 1", "author": { @@ -275,3 +275,38 @@ def test_linked_relationship(): } } } + + +def test_type_relationship(): + response = { + "data": { + "type": "article", + "id": "1", + "attributes": { + "title": "Article 1" + }, + "relationships": { + "type": { + "data": {"type": "article-type", "id": "9"} + } + } + }, + "included": [{ + "type": "article-type", + "id": "9", + "attributes": { + "field": "value" + } + }] + } + doc = json_api_doc.parse(response) + assert doc == { + "$type": "article", + "id": "1", + "title": "Article 1", + "type": { + "$type": "article-type", + "id": "9", + "field": "value" + } + } diff --git a/tests/test_simple.py b/tests/test_simple.py index 7680b3a..57b9123 100644 --- a/tests/test_simple.py +++ b/tests/test_simple.py @@ -29,7 +29,7 @@ def test_simple_object(): } doc = json_api_doc.parse(response) assert doc == { - "type": "article", + "$type": "article", "id": "1", "title": "Article 1" } @@ -44,7 +44,7 @@ def test_simple_object_without_attributes(): } doc = json_api_doc.parse(response) assert doc == { - "type": "article", + "$type": "article", "id": "1" } @@ -71,12 +71,12 @@ def test_simple_list(): doc = json_api_doc.parse(response) assert len(doc) == 2 assert doc[0] == { - "type": "article", + "$type": "article", "id": "1", "title": "Article 1" } assert doc[1] == { - "type": "article", + "$type": "article", "id": "2", "title": "Article 2" }