From ffe9f148821b971fcb8cb69b8cadb6c661256668 Mon Sep 17 00:00:00 2001
From: Jean-Baptiste <bleme@pm.me>
Date: Thu, 14 Feb 2019 11:48:06 +0100
Subject: [PATCH] update: accept another input format

---
 djangoldp/serializers.py        | 11 ++++--
 djangoldp/tests/tests_update.py | 59 ++++++++++++++++++++++++++++++---
 2 files changed, 64 insertions(+), 6 deletions(-)

diff --git a/djangoldp/serializers.py b/djangoldp/serializers.py
index 80510749..7b627da1 100644
--- a/djangoldp/serializers.py
+++ b/djangoldp/serializers.py
@@ -8,7 +8,7 @@ from django.utils.datastructures import MultiValueDictKeyError
 from django.utils.encoding import uri_to_iri
 from guardian.shortcuts import get_perms
 from rest_framework.exceptions import ValidationError
-from rest_framework.fields import SkipField
+from rest_framework.fields import SkipField, empty
 from rest_framework.fields import get_error_detail, set_value
 from rest_framework.relations import HyperlinkedRelatedField, ManyRelatedField, MANY_RELATION_KWARGS
 from rest_framework.serializers import HyperlinkedModelSerializer, ListSerializer
@@ -44,7 +44,12 @@ class LDListMixin:
             view_name = '{}-list'.format(self.parent.Meta.model._meta.object_name.lower())
             part_id = '/{}'.format(get_resolver().reverse_dict[view_name][0][0][0], self.parent.instance.pk)
             obj = next(filter(lambda o: part_id in o['@id'], object_list))
-            list = super().get_value(obj);
+            list = super().get_value(obj)
+            try:
+                list = next(filter(lambda o: list['@id'] == o['@id'], object_list))
+            except KeyError:
+                pass
+
             try:
                 list = list['ldp:contains']
             except KeyError:
@@ -290,6 +295,8 @@ class LDPSerializer(HyperlinkedModelSerializer):
             obj = next(filter(lambda o: part_id in o[self.url_field_name], object_list))
             item = super().get_value(obj)
             full_item = None
+            if item is empty:
+                return empty
             try:
                 full_item = next(filter(lambda o: item['@id'] == o['@id'], object_list))
             except StopIteration:
diff --git a/djangoldp/tests/tests_update.py b/djangoldp/tests/tests_update.py
index a4033acb..b129716f 100644
--- a/djangoldp/tests/tests_update.py
+++ b/djangoldp/tests/tests_update.py
@@ -35,7 +35,7 @@ class Serializer(TestCase):
         self.assertIs(result.skills.count(), 3)
         skills = result.skills.all().order_by('title')
         self.assertEquals(skills[0].title, "new skill")  # new skill
-        self.assertEquals(skills[1].title, "skill1")     # no change
+        self.assertEquals(skills[1].title, "skill1")  # no change
         self.assertEquals(skills[2].title, "skill2 UP")  # title updated
 
     def test_update_graph(self):
@@ -55,7 +55,7 @@ class Serializer(TestCase):
                                ]}
                            },
                           {
-                             "@id": "_.123",
+                              "@id": "_.123",
                               "title": "new skill",
                               "obligatoire": "okay"
                           },
@@ -66,7 +66,7 @@ class Serializer(TestCase):
                               "@id": "https://happy-dev.fr/skills/{}/".format(skill2.pk),
                               "title": "skill2 UP"
                           }]
-            }
+               }
 
         meta_args = {'model': JobOffer, 'depth': 1, 'fields': ("@id", "title", "skills")}
 
@@ -81,5 +81,56 @@ class Serializer(TestCase):
         self.assertEquals(result.title, "job test updated")
         self.assertIs(result.skills.count(), 3)
         self.assertEquals(skills[0].title, "new skill")  # new skill
-        self.assertEquals(skills[1].title, "skill1")     # no change
+        self.assertEquals(skills[1].title, "skill1")  # no change
         self.assertEquals(skills[2].title, "skill2 UP")  # title updated
+
+        def test_update_graph_2(self):
+            skill = Skill.objects.create(title="to drop", obligatoire="obligatoire")
+            skill1 = Skill.objects.create(title="skill1", obligatoire="obligatoire")
+            skill2 = Skill.objects.create(title="skill2", obligatoire="obligatoire")
+            job1 = JobOffer.objects.create(title="job test")
+            job1.skills.add(skill)
+
+            job = {"@graph":[{"@id": "https://happy-dev.fr/job-offers/{}/".format(job1.pk),
+                               "title": "job test updated",
+                               "skills": {
+                                   "@id": "https://happy-dev.fr/job-offers/{}/skills/".format(job1.pk)
+                                    }
+                              },
+                              {
+                                  "@id": "_.123",
+                                  "title": "new skill",
+                                  "obligatoire": "okay"
+                              },
+                              {
+                                  "@id": "https://happy-dev.fr/skills/{}/".format(skill1.pk),
+                              },
+                              {
+                                  "@id": "https://happy-dev.fr/skills/{}/".format(skill2.pk),
+                                  "title": "skill2 UP"
+                              },
+                              {
+                                  '@id': "https://happy-dev.fr/job-offers/{}/skills/".format(job1.pk),
+                                  "ldp:contains": [
+                                      {"@id": "https://happy-dev.fr/skills/{}/".format(skill1.pk)},
+                                      {"@id": "https://happy-dev.fr/skills/{}/".format(skill2.pk)},
+                                      {"@id": "_.123"},
+                                  ]
+                              }]
+                   }
+
+            meta_args = {'model': JobOffer, 'depth': 1, 'fields': ("@id", "title", "skills")}
+
+            meta_class = type('Meta', (), meta_args)
+            serializer_class = type(LDPSerializer)('JobOfferSerializer', (LDPSerializer,), {'Meta': meta_class})
+            serializer = serializer_class(data=job, instance=job1)
+            serializer.is_valid()
+            result = serializer.save()
+
+            skills = result.skills.all().order_by('title')
+
+            self.assertEquals(result.title, "job test updated")
+            self.assertIs(result.skills.count(), 3)
+            self.assertEquals(skills[0].title, "new skill")  # new skill
+            self.assertEquals(skills[1].title, "skill1")  # no change
+            self.assertEquals(skills[2].title, "skill2 UP")  # title updated
-- 
GitLab