This repository has been archived by the owner on Feb 9, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added the endpoints, and test coverage for all functionality but the …
…third-party API integration.
- Loading branch information
1 parent
f03bccc
commit 02278fa
Showing
5 changed files
with
165 additions
and
39 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,59 @@ | ||
from flask import Flask | ||
from flask import Flask, request, Response | ||
from werkzeug.exceptions import NotAcceptable, UnsupportedMediaType, NotFound | ||
|
||
from tk.process import Process | ||
|
||
|
||
def request_content_type(content_type): | ||
""" | ||
Check we can accept the request body. | ||
:param content_type: | ||
:return: | ||
""" | ||
def decorator(route_method): | ||
def checker(*route_method_args, **route_method_kwargs): | ||
if request.mimetype != content_type: | ||
raise UnsupportedMediaType() | ||
return route_method(*route_method_args, **route_method_kwargs) | ||
return checker | ||
return decorator | ||
|
||
|
||
def response_content_type(content_type): | ||
""" | ||
Check we can deliver the right content type. | ||
:return: | ||
""" | ||
def decorator(route_method): | ||
def checker(*route_method_args, **route_method_kwargs): | ||
negotiated_content_type = request.accept_mimetypes.best_match( | ||
[content_type]) | ||
if negotiated_content_type is None: | ||
raise NotAcceptable() | ||
return route_method(*route_method_args, **route_method_kwargs) | ||
return checker | ||
return decorator | ||
|
||
|
||
class App(Flask): | ||
def __init__(self, *args, **kwargs): | ||
super().__init__('tk', *args, **kwargs) | ||
super().__init__('tk', static_folder=None, *args, **kwargs) | ||
self._register_routes() | ||
self.process = Process() | ||
|
||
def _register_routes(self): | ||
@self.route('/submit', methods=['POST']) | ||
@self.route('/submit', methods=['POST'], endpoint='submit') | ||
@request_content_type('application/octet-stream') | ||
@response_content_type('text/plain') | ||
def submit(): | ||
return 'SUBMITTED' | ||
process_id = self.process.submit() | ||
return Response(process_id, 200, mimetype='text/plain') | ||
|
||
@self.route('/retrieve/<id>') | ||
def retrieve(id): | ||
return id | ||
@self.route('/retrieve/<process_id>', endpoint='retrieve') | ||
@request_content_type('') | ||
@response_content_type('text/xml') | ||
def retrieve(process_id): | ||
result = self.process.retrieve(process_id) | ||
if result is None: | ||
raise NotFound() | ||
return Response(result, 200, mimetype='text/plain') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import uuid | ||
|
||
|
||
class Process: | ||
def __init__(self): | ||
self._processes = {} | ||
|
||
def submit(self): | ||
process_id = str(uuid.uuid4()) | ||
self._processes[process_id] = 'PROGRESS' | ||
return process_id | ||
|
||
def retrieve(self, process_id): | ||
if process_id not in self._processes: | ||
return None | ||
return self._processes[process_id] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
from tk.tests import IntegrationTestCase, data_provider | ||
|
||
|
||
def provide_disallowed_submit_methods(): | ||
return { | ||
'GET': ('GET',), | ||
'PUT': ('PUT',), | ||
'PATCH': ('PATCH',), | ||
'DELETE': ('DELETE',), | ||
} | ||
|
||
|
||
def provide_disallowed_retrieve_methods(): | ||
return { | ||
'POST': ('POST',), | ||
'PUT': ('PUT',), | ||
'PATCH': ('PATCH',), | ||
'DELETE': ('DELETE',), | ||
} | ||
|
||
|
||
class SubmitTest(IntegrationTestCase): | ||
@data_provider(provide_disallowed_submit_methods) | ||
def testSubmitWithDisallowedMethodShould405(self, method): | ||
response = self._flask_app_client.open('/submit', method=method) | ||
self.assertEquals(405, response.status_code) | ||
|
||
def testSubmitWithUnsupportedMediaTypeShould415(self): | ||
response = self._flask_app_client.post('/submit') | ||
self.assertEquals(415, response.status_code) | ||
|
||
def testSubmitWithNotAcceptableShould406(self): | ||
response = self._flask_app_client.post('/submit', headers={ | ||
'Content-Type': 'application/octet-stream' | ||
}) | ||
self.assertEquals(406, response.status_code) | ||
|
||
def testSubmit(self): | ||
response = self._flask_app_client.post('/submit', headers={ | ||
'Accept': 'text/plain', | ||
'Content-Type': 'application/octet-stream' | ||
}) | ||
self.assertEquals(200, response.status_code) | ||
# Assert the response contains a plain-text process UUID. | ||
self.assertRegex(response.get_data( | ||
as_text=True), '[a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}') | ||
|
||
|
||
class RetrieveTest(IntegrationTestCase): | ||
@data_provider(provide_disallowed_retrieve_methods) | ||
def testRetrieveWithDisallowedMethodShould405(self, method): | ||
response = self._flask_app_client.open('/retrieve/foo', method=method) | ||
self.assertEquals(response.status_code, 405) | ||
|
||
def testRetrieveWithUnsupportedMediaTypeShould415(self): | ||
response = self._flask_app_client.get('/retrieve/foo', headers={ | ||
'Content-Type': 'text/plain', | ||
}) | ||
self.assertEquals(response.status_code, 415) | ||
|
||
def testRetrieveWithNotAcceptableShould406(self): | ||
response = self._flask_app_client.get('/retrieve/foo') | ||
self.assertEquals(response.status_code, 406) | ||
|
||
def testRetrieveWithUnknownProcessIdShould404(self): | ||
response = self._flask_app_client.get('/retrieve/foo', headers={ | ||
'Accept': 'text/xml', | ||
}) | ||
self.assertEquals(response.status_code, 404) | ||
|
||
def testRetrieveWithUnprocessedDocument(self): | ||
process_id = self._flask_app.process.submit() | ||
response = self._flask_app_client.get('/retrieve/%s' % process_id, headers={ | ||
'Accept': 'text/xml', | ||
}) | ||
self.assertEquals(response.status_code, 200) | ||
self.assertEquals(response.get_data(as_text=True), 'PROGRESS') | ||
|
||
def testRetrieveWithProcessedDocument(self): | ||
process_id = self._flask_app.process.submit() | ||
response = self._flask_app_client.get('/retrieve/%s' % process_id, headers={ | ||
'Accept': 'text/xml', | ||
}) | ||
self.assertEquals(response.status_code, 200) | ||
# @todo Confirm output. | ||
self.skipTest() |
This file was deleted.
Oops, something went wrong.