From 94827e1d39f369106894fb4a020e6b8e69e18c46 Mon Sep 17 00:00:00 2001 From: David Moreau Simard Date: Thu, 21 Jun 2018 16:29:45 -0400 Subject: [PATCH] Implement get_or_create functionality for the host endpoint This commit essentially makes it so the "unique together" constraint for host.name -> play.id is enforced through a get_or_create approach instead. Change-Id: I9b9c015fa2f4dec4d99f051fa102fd422263fe0f --- ara/api/serializers.py | 17 +++++++++++++++++ ara/api/tests/test_host.py | 22 ++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/ara/api/serializers.py b/ara/api/serializers.py index ac7710a..73ce55f 100644 --- a/ara/api/serializers.py +++ b/ara/api/serializers.py @@ -112,6 +112,23 @@ class HostSerializer(serializers.ModelSerializer): facts = CompressedObjectField(default=zlib.compress(json.dumps({}).encode('utf8'))) + def get_unique_together_validators(self): + ''' + Hosts have a "unique together" constraint for host.name and play.id. + We want to have a "get_or_create" facility and in order to do that, we + must manage the validation during the creation, not before. + Overriding this method effectively disables this validator. + ''' + return [] + + def create(self, validated_data): + host, created = models.Host.objects.get_or_create( + name=validated_data['name'], + play=validated_data['play'], + defaults=validated_data + ) + return host + class ResultSerializer(serializers.ModelSerializer): class Meta: diff --git a/ara/api/tests/test_host.py b/ara/api/tests/test_host.py index e7a863a..1140cee 100644 --- a/ara/api/tests/test_host.py +++ b/ara/api/tests/test_host.py @@ -85,6 +85,28 @@ class HostTestCase(APITestCase): self.assertEqual(201, request.status_code) self.assertEqual(1, models.Host.objects.count()) + def test_post_same_host_for_a_play(self): + play = factories.PlayFactory() + self.assertEqual(0, models.Host.objects.count()) + request = self.client.post('/api/v1/hosts/', { + 'name': 'create', + 'play': play.id, + 'ok': 1 + }) + self.assertEqual(201, request.status_code) + self.assertEqual(1, models.Host.objects.count()) + self.assertEqual(1, request.data['ok']) + + request = self.client.post('/api/v1/hosts/', { + 'name': 'create', + 'play': play.id, + 'ok': 2 + }) + self.assertEqual(201, request.status_code) + self.assertEqual(1, models.Host.objects.count()) + # This isn't expected to update the count for 'ok', it's not a patch + self.assertEqual(1, request.data['ok']) + def test_partial_update_host(self): host = factories.HostFactory() self.assertNotEqual(1, host.ok)