Skip to content
Snippets Groups Projects
Verified Commit b96e67e1 authored by David Beniamine's avatar David Beniamine
Browse files

All CRUD tests passing

parent a013bb51
No related branches found
No related tags found
1 merge request!2Draft:Generic api v1
...@@ -22,7 +22,7 @@ class BaseModel(DeclarativeBase): ...@@ -22,7 +22,7 @@ class BaseModel(DeclarativeBase):
engine = getApp().db.engine engine = getApp().db.engine
"""Access the db session""" """Access the db session"""
fillable = [] fillable = ['id']
"""Field that can be overriden by self.fill()""" """Field that can be overriden by self.fill()"""
id = mapped_column(Integer, primary_key=True) id = mapped_column(Integer, primary_key=True)
...@@ -138,6 +138,7 @@ class BaseModel(DeclarativeBase): ...@@ -138,6 +138,7 @@ class BaseModel(DeclarativeBase):
def clear(self): def clear(self):
"""Clears all the fields of the object""" """Clears all the fields of the object"""
for x in self.fields.keys(): for x in self.fields.keys():
if x != 'id':
setattr(self, x, None) setattr(self, x, None)
return self return self
...@@ -177,8 +178,8 @@ class MiradorResource(BaseModel): ...@@ -177,8 +178,8 @@ class MiradorResource(BaseModel):
content = mapped_column(JSON) content = mapped_column(JSON)
"""JSON content of the resource""" """JSON content of the resource"""
fillable = ['content'] fillable = BaseModel.fillable + ['content']
fields = { fields = BaseModel.fields | {
'id': fields.Integer, 'id': fields.Integer,
'content': fields.String 'content': fields.String
} }
...@@ -10,6 +10,9 @@ from flask_apispec import doc ...@@ -10,6 +10,9 @@ from flask_apispec import doc
from flask_restful import marshal, fields from flask_restful import marshal, fields
from Mirador_backend.models import BaseModel, NotFound from Mirador_backend.models import BaseModel, NotFound
from Mirador_backend.utils.app import getApp
logger = getApp().logger
class ResourceGroup(MethodResource, Resource): class ResourceGroup(MethodResource, Resource):
...@@ -17,7 +20,7 @@ class ResourceGroup(MethodResource, Resource): ...@@ -17,7 +20,7 @@ class ResourceGroup(MethodResource, Resource):
def parseData(self, request): def parseData(self, request):
"""Read the request and return only the useful data""" """Read the request and return only the useful data"""
return request.form return request.json
def get_queryset(self): def get_queryset(self):
"""Get the queryset for the request""" """Get the queryset for the request"""
...@@ -31,7 +34,7 @@ class ResourceGroup(MethodResource, Resource): ...@@ -31,7 +34,7 @@ class ResourceGroup(MethodResource, Resource):
def post(self): def post(self):
"""Handle a post request""" """Handle a post request"""
m = Model().create(self.parseData(request)) m = self.Model().create(self.parseData(request))
return marshal(m, self.Model.fields), 200 return marshal(m, self.Model.fields), 200
def genDoc(descr, tags): def genDoc(descr, tags):
...@@ -55,7 +58,7 @@ class ResourceItem(MethodResource, Resource): ...@@ -55,7 +58,7 @@ class ResourceItem(MethodResource, Resource):
def parseData(self, request): def parseData(self, request):
"""Read the request and return only the useful data""" """Read the request and return only the useful data"""
return request.form return request.json
def get(self, id): def get(self, id):
"""Handle a get request""" """Handle a get request"""
...@@ -70,21 +73,21 @@ class ResourceItem(MethodResource, Resource): ...@@ -70,21 +73,21 @@ class ResourceItem(MethodResource, Resource):
m.fill(data) m.fill(data)
m = m.save() m = m.save()
except NotFound: except NotFound:
m = self.Model.create(data) data['id'] = id
return marshal(model, self.Model.fields), 200 m = self.Model().create(data)
return marshal(m, self.Model.fields), 200
def patch(self, id): def patch(self, id):
"""Handle a patch request""" """Handle a patch request"""
m = self.get_queryset_or_abort(id) m = self.get_queryset_or_abort(id)
m.clear()
m.fill(self.parseData(request)) 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): def delete(self, id):
"""Handle a delete request""" """Handle a delete request"""
m = self.get_queryset_or_abort(id) 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): def genDoc(descr, tags):
doc(description=f'Get {descr} by id', tags=tags)(ResourceItem.get) doc(description=f'Get {descr} by id', tags=tags)(ResourceItem.get)
......
...@@ -4,21 +4,60 @@ from Mirador_backend.tests.tester import TestCase ...@@ -4,21 +4,60 @@ from Mirador_backend.tests.tester import TestCase
class MiradorResourceTest(TestCase): class MiradorResourceTest(TestCase):
headers = {"Content-Type": "application/json"}
def getData(self): def getData(self):
return self.getFixtureRecordsByModel(self.fixtures[0], 'Mirador_backend.models.MiradorResource') 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): def testGetOne(self):
id = 1 self.get(1)
payload = json.dumps({})
response = self.client.get(f'{self.base}/{id}', headers={"Content-Type": "application/json"}, data=payload)
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) def testPut(self):
self.assertEqual(expected, response.json) 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): def testPost(self):
payload = json.dumps({}) id = 2
response = self.client.get(self.base, headers={"Content-Type": "application/json"}, data=payload) self.get(id, False)
self.assertEqual(200, response.status_code) data = {'content': '{"a":"b"}'}
self.assertEqual({str(x['id']): x for x in self.getData()}, response.json) 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)
...@@ -16,6 +16,9 @@ class TestCase(unittest.TestCase, FixturesMixin): ...@@ -16,6 +16,9 @@ class TestCase(unittest.TestCase, FixturesMixin):
self.base = 'v1/mirador_resource' self.base = 'v1/mirador_resource'
self.client = app.test_client() self.client = app.test_client()
def tearDown(self):
pass
def getFixture(self, name): def getFixture(self, name):
with open(f'{dirname(abspath(__file__))}/fixtures/{name}') as f: with open(f'{dirname(abspath(__file__))}/fixtures/{name}') as f:
return json.load(f) return json.load(f)
...@@ -23,6 +26,9 @@ class TestCase(unittest.TestCase, FixturesMixin): ...@@ -23,6 +26,9 @@ class TestCase(unittest.TestCase, FixturesMixin):
def getFixtureRecordsByModel(self, name, model): def getFixtureRecordsByModel(self, name, model):
return next(x['records'] for x in self.getFixture(name) if x['model'] == model) return next(x['records'] for x in self.getFixture(name) if x['model'] == model)
def tearDown(self): def assertBadResponse(self, response, expectedCode):
# TODO self.assertEqual(expectedCode, response.status_code)
pass
def assertGoodResponse(self, response, expectedData):
self.assertEqual(200, response.status_code)
self.assertEqual(expectedData, response.json)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment