From b96e67e1d05ec8f81789648577c2bd763df200c9 Mon Sep 17 00:00:00 2001
From: David Beniamine <david.beniamine@tetras-libre.fr>
Date: Thu, 16 Feb 2023 00:32:31 +0100
Subject: [PATCH] All CRUD tests passing

---
 Mirador_backend/models.py                     |  9 +--
 Mirador_backend/resources/base.py             | 21 ++++---
 .../tests/test_mirador_resource.py            | 61 +++++++++++++++----
 Mirador_backend/tests/tester.py               | 12 +++-
 4 files changed, 76 insertions(+), 27 deletions(-)

diff --git a/Mirador_backend/models.py b/Mirador_backend/models.py
index c35529c..e6e15a9 100644
--- a/Mirador_backend/models.py
+++ b/Mirador_backend/models.py
@@ -22,7 +22,7 @@ class BaseModel(DeclarativeBase):
     engine = getApp().db.engine
     """Access the db session"""
 
-    fillable = []
+    fillable = ['id']
     """Field that can be overriden by self.fill()"""
 
     id = mapped_column(Integer, primary_key=True)
@@ -138,7 +138,8 @@ class BaseModel(DeclarativeBase):
     def clear(self):
         """Clears all the fields of the object"""
         for x in self.fields.keys():
-            setattr(self, x, None)
+            if x != 'id':
+                setattr(self, x, None)
         return self
 
     def create(self, data):
@@ -177,8 +178,8 @@ class MiradorResource(BaseModel):
     content = mapped_column(JSON)
     """JSON content of the resource"""
 
-    fillable = ['content']
-    fields = {
+    fillable = BaseModel.fillable + ['content']
+    fields = BaseModel.fields | {
         'id': fields.Integer,
         'content': fields.String
         }
diff --git a/Mirador_backend/resources/base.py b/Mirador_backend/resources/base.py
index ab1721e..e264ec2 100644
--- a/Mirador_backend/resources/base.py
+++ b/Mirador_backend/resources/base.py
@@ -10,6 +10,9 @@ from flask_apispec import doc
 from flask_restful import marshal, fields
 
 from Mirador_backend.models import BaseModel, NotFound
+from Mirador_backend.utils.app import getApp
+
+logger = getApp().logger
 
 
 class ResourceGroup(MethodResource, Resource):
@@ -17,7 +20,7 @@ class ResourceGroup(MethodResource, Resource):
 
     def parseData(self, request):
         """Read the request and return only the useful data"""
-        return request.form
+        return request.json
 
     def get_queryset(self):
         """Get the queryset for the request"""
@@ -31,7 +34,7 @@ class ResourceGroup(MethodResource, Resource):
 
     def post(self):
         """Handle a post request"""
-        m = Model().create(self.parseData(request))
+        m = self.Model().create(self.parseData(request))
         return marshal(m, self.Model.fields), 200
 
     def genDoc(descr, tags):
@@ -55,7 +58,7 @@ class ResourceItem(MethodResource, Resource):
 
     def parseData(self, request):
         """Read the request and return only the useful data"""
-        return request.form
+        return request.json
 
     def get(self, id):
         """Handle a get request"""
@@ -70,21 +73,21 @@ class ResourceItem(MethodResource, Resource):
             m.fill(data)
             m = m.save()
         except NotFound:
-            m = self.Model.create(data)
-        return marshal(model, self.Model.fields), 200
-
+            data['id'] = id
+            m = self.Model().create(data)
+        return marshal(m, self.Model.fields), 200
 
     def patch(self, id):
         """Handle a patch request"""
         m = self.get_queryset_or_abort(id)
-        m.clear()
         m.fill(self.parseData(request))
-        return marshal(m.save(), self.Model.fields), 200
+        m.save()
+        return marshal(m, self.Model.fields), 200
 
     def delete(self, id):
         """Handle a delete request"""
         m = self.get_queryset_or_abort(id)
-        return marshal(m.delete(), fields.Boolean), 200
+        return marshal({'success': m.delete()}, {'success': fields.Boolean}), 200
 
     def genDoc(descr, tags):
         doc(description=f'Get {descr} by id', tags=tags)(ResourceItem.get)
diff --git a/Mirador_backend/tests/test_mirador_resource.py b/Mirador_backend/tests/test_mirador_resource.py
index a0a0558..29e89b4 100644
--- a/Mirador_backend/tests/test_mirador_resource.py
+++ b/Mirador_backend/tests/test_mirador_resource.py
@@ -4,21 +4,60 @@ from Mirador_backend.tests.tester import TestCase
 
 
 class MiradorResourceTest(TestCase):
+    headers = {"Content-Type": "application/json"}
+
     def getData(self):
         return self.getFixtureRecordsByModel(self.fixtures[0], 'Mirador_backend.models.MiradorResource')
 
+    def get(self, id, inFixtures=True, raw=None):
+        response = self.client.get(f'{self.base}/{id}', headers=self.headers)
+        if inFixtures:
+            self.assertGoodResponse(response, next(x for x in self.getData() if x['id'] == 1))
+        elif raw is not None:
+            self.assertGoodResponse(response, raw)
+        else:
+            self.assertBadResponse(response, 404)
+
     def testGetOne(self):
-        id = 1
-        payload = json.dumps({})
-        response = self.client.get(f'{self.base}/{id}', headers={"Content-Type": "application/json"}, data=payload)
+        self.get(1)
 
-        self.assertEqual(200, response.status_code)
+    def testGetAll(self):
+        response = self.client.get(self.base, headers=self.headers)
+        self.assertGoodResponse(response, {str(x['id']): x for x in self.getData()})
 
-        expected = next(x for x in self.getData() if x['id'] == id)
-        self.assertEqual(expected, response.json)
+    def testPut(self):
+        id = 3
+        self.get(id, False)
+        data = {'content': '{"a":"b"}'}
+        payload = json.dumps(data)
+        response = self.client.put(f'{self.base}/{id}', headers=self.headers, data=payload)
+        data['id'] = id
+        self.assertGoodResponse(response, data)
+        self.get(id, False, data)
 
-    def testGetAll(self):
-        payload = json.dumps({})
-        response = self.client.get(self.base, headers={"Content-Type": "application/json"}, data=payload)
-        self.assertEqual(200, response.status_code)
-        self.assertEqual({str(x['id']): x for x in self.getData()}, response.json)
+    def testPost(self):
+        id = 2
+        self.get(id, False)
+        data = {'content': '{"a":"b"}'}
+        payload = json.dumps(data)
+        response = self.client.post(f'{self.base}', headers=self.headers, data=payload)
+        data['id'] = id
+        self.assertGoodResponse(response, data)
+        self.get(id, False, data)
+
+    def testPatch(self):
+        id = 1
+        self.get(id)
+        data = {'content': '{"a":"b"}'}
+        payload = json.dumps(data)
+        response = self.client.patch(f'{self.base}/{id}', headers=self.headers, data=payload)
+        data['id'] = id
+        self.assertGoodResponse(response, data)
+        self.get(id, False, data)
+
+    def testDelete(self):
+        id = 1
+        self.get(id)
+        response = self.client.delete(f'{self.base}/{id}', headers=self.headers)
+        self.assertGoodResponse(response, {'success': True})
+        self.get(id,  False)
diff --git a/Mirador_backend/tests/tester.py b/Mirador_backend/tests/tester.py
index 57a9bff..f2f6882 100644
--- a/Mirador_backend/tests/tester.py
+++ b/Mirador_backend/tests/tester.py
@@ -16,6 +16,9 @@ class TestCase(unittest.TestCase, FixturesMixin):
         self.base = 'v1/mirador_resource'
         self.client = app.test_client()
 
+    def tearDown(self):
+        pass
+
     def getFixture(self, name):
         with open(f'{dirname(abspath(__file__))}/fixtures/{name}') as f:
             return json.load(f)
@@ -23,6 +26,9 @@ class TestCase(unittest.TestCase, FixturesMixin):
     def getFixtureRecordsByModel(self, name, model):
         return next(x['records'] for x in self.getFixture(name) if x['model'] == model)
 
-    def tearDown(self):
-        # TODO
-        pass
+    def assertBadResponse(self, response, expectedCode):
+        self.assertEqual(expectedCode, response.status_code)
+
+    def assertGoodResponse(self, response, expectedData):
+        self.assertEqual(200, response.status_code)
+        self.assertEqual(expectedData, response.json)
-- 
GitLab