Skip to content

Commit

Permalink
Merge pull request #15 from reiterl/dev_issues
Browse files Browse the repository at this point in the history
Add get_resource and upload_resource routes.
  • Loading branch information
FinnStutzenstein committed Jan 12, 2021
2 parents cdf1b72 + 6c5a377 commit 6db3ecb
Show file tree
Hide file tree
Showing 9 changed files with 229 additions and 51 deletions.
11 changes: 7 additions & 4 deletions src/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,19 @@
AUTH_HEADER = "Authentication"


def check_mediafile_id(mediafile_id, app, presenter_headers):
def check_file_id(file_id, file_type, app, presenter_headers):
"""
Returns a triple: ok, filename, auth_header.
filename is given, if ok=True. If ok=false, the user has no perms.
if auth_header is returned, it must be set in the response.
"""
presenter_url = get_presenter_url(app)
payload = [
{"presenter": "check_mediafile_id", "data": {"mediafile_id": mediafile_id}}
]
if file_type == "mediafile":
payload = [
{"presenter": "check_mediafile_id", "data": {"mediafile_id": file_id}}
]
elif file_type == "resource":
payload = [{"presenter": "check_resource_id", "data": {"resource_id": file_id}}]
app.logger.debug(f"Send check request: {presenter_url}: {payload}")

try:
Expand Down
51 changes: 34 additions & 17 deletions src/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,23 @@ def __init__(self, app):
self.config = app.config
self.logger = app.logger
self.connection = None
self.cache = LRUCache(self.logger, 20)
self.cache_mediafile = LRUCache(self.logger, 20)
self.cache_resource = LRUCache(self.logger, 20)

def get_mediafile(self, media_id):
if self.cache.has_media_id(media_id):
return self.cache.get_media(media_id)
def get_file(self, file_id, file_type):
if file_type == "mediafile" and self.cache_mediafile.has_media_id(file_id):
return self.cache_mediafile.get_media(file_id)
elif file_type == "resource" and self.cache_resource.has_media_id(file_id):
return self.cache_resource.get_media(file_id)
while True:
connection = self.get_connection()
try:
with connection:
media = self._query(connection, media_id)
self.cache.set_media(media_id, media)
media = self._query(connection, file_id, file_type)
if file_type == "mediafile":
self.cache_mediafile.set_media(file_id, media)
elif file_type == "resource":
self.cache_resource.set_media(file_id, media)
return media
except psycopg2.InterfaceError:
if self.connection:
Expand All @@ -30,24 +36,26 @@ def get_mediafile(self, media_id):
self.logger.error(f"Error during retrieving a mediafile: " f"{repr(e)}")
raise ServerError(f"Database error {e.pgcode}: {e.pgerror}")

def _query(self, connection, media_id):
def _query(self, connection, file_id, file_type):
with connection.cursor() as cur:
cur.execute(
"SELECT data, mimetype FROM mediafile_data WHERE id=%s", [media_id]
)
if file_type == "mediafile":
fetch_query = "SELECT data, mimetype FROM mediafile_data WHERE id=%s"
elif file_type == "resource":
fetch_query = "SELECT data, mimetype FROM resource_data WHERE id=%s"
cur.execute(fetch_query, [file_id])
row = cur.fetchone()
if not row:
raise ServerError(
f"The mediafile with id {media_id} could not be found."
f"The {file_type} with id {file_id} could not be found."
)
return (row[0], row[1])

def set_mediafile(self, media_id, media, mimetype):
def set_mediafile(self, file_id, file_type, media, mimetype):
while True:
try:
connection = self.get_connection()
with connection:
self._insert(connection, media_id, media, mimetype)
self._insert(connection, file_id, file_type, media, mimetype)
break
except psycopg2.InterfaceError:
if self.connection:
Expand All @@ -58,12 +66,21 @@ def set_mediafile(self, media_id, media, mimetype):
self.logger.error(f"Error during inserting a mediafile: {repr(e)}")
raise ServerError(f"Database error {e.pgcode}: {e.pgerror}")

def _insert(self, connection, media_id, media, mimetype):
def _insert(self, connection, file_id, file_type, media, mimetype):
if file_type == "mediafile":
insert_sql = (
"INSERT INTO mediafile_data (id, data, mimetype) "
" VALUES (%s, %s, %s)"
)
elif file_type == "resource":
insert_sql = (
"INSERT INTO resource_data (id, data, mimetype) " " VALUES (%s, %s, %s)"
)

with connection.cursor() as cur:
cur.execute(
"INSERT INTO mediafile_data (id, data, mimetype) "
" VALUES (%s, %s, %s)",
(media_id, media, mimetype),
insert_sql,
(file_id, media, mimetype),
)

def get_connection(self):
Expand Down
42 changes: 31 additions & 11 deletions src/mediaserver.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from flask import Flask, Response, jsonify, request

from .auth import AUTH_HEADER, check_mediafile_id
from .auth import AUTH_HEADER, check_file_id
from .config_handling import init_config
from .database import Database
from .exceptions import BadRequestError, HttpError, NotFoundError
Expand Down Expand Up @@ -32,20 +32,31 @@ def handle_view_error(error):

@app.route("/system/media/get/<int:mediafile_id>")
def serve(mediafile_id):
# get mediafile id
return serve_files(mediafile_id, "mediafile")


@app.route("/system/media/get_resource/<int:resource_id>")
def serve_resource(resource_id):
return serve_files(resource_id, "resource")


def serve_files(file_id, file_type):
# get file id
presenter_headers = dict(request.headers)
del_keys = [key for key in presenter_headers if "content" in key]
for key in del_keys:
del presenter_headers[key]
ok, filename, auth_header = check_mediafile_id(mediafile_id, app, presenter_headers)
ok, filename, auth_header = check_file_id(
file_id, file_type, app, presenter_headers
)
if not ok:
raise NotFoundError()

app.logger.debug(f'Filename for "{mediafile_id}" is {filename}')
app.logger.debug(f'Filename for "{file_id}" is {filename}')

# Query file from db
global database
data, mimetype = database.get_mediafile(mediafile_id)
data, mimetype = database.get_file(file_id, file_type)

# Send data (chunked)
def chunked(size, source):
Expand All @@ -60,28 +71,37 @@ def chunked(size, source):
return response


@app.route("/internal/media/upload/", methods=["POST"])
@app.route("/internal/media/upload_mediafile/", methods=["POST"])
def media_post():
return file_post("mediafile")


@app.route("/internal/media/upload_resource/", methods=["POST"])
def resource_post():
return file_post("resource")


def file_post(file_type):
try:
decoded = request.data.decode()
dejson = json.loads(decoded)
except Exception:
raise BadRequestError("request.data is not json")
try:
media = base64.b64decode(dejson["file"].encode())
file_data = base64.b64decode(dejson["file"].encode())
except Exception:
raise BadRequestError("cannot decode base64 file")
try:
media_id = int(dejson["id"])
file_id = int(dejson["id"])
mimetype = dejson["mimetype"]
except Exception:
raise BadRequestError(
f"The post request.data is not in right format: {request.data}"
)
app.logger.debug(f"to database media {media_id} {mimetype}")
app.logger.debug(f"to database {file_type} {file_id} {mimetype}")
global database
database.set_mediafile(media_id, media, mimetype)
return f"Mediaserver: add {media_id} to db", 200
database.set_mediafile(file_id, file_type, file_data, mimetype)
return "", 200


def shutdown(database):
Expand Down
6 changes: 6 additions & 0 deletions src/schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,9 @@ CREATE TABLE IF NOT EXISTS mediafile_data (
data bytea,
mimetype varchar(255)
);

CREATE TABLE IF NOT EXISTS resource_data (
id int PRIMARY KEY,
data bytea,
mimetype varchar(255)
);
13 changes: 7 additions & 6 deletions src/test_data.sql
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
INSERT INTO mediafile_data VALUES (3, 'test222', 'image/jpeg') ,
(2, 'a2', 'text/plain')
ON CONFLICT DO NOTHING;
INSERT INTO mediafile_data VALUES
(3, '\x89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b000000017352474200aece1ce900000006624b474400ff00ff00ffa0bda793000000097048597300000dd700000dd70142289b780000000774494d4507da0a070821340b2e051f000005364944415438cb8d955b6c5c471dc67f3373ced99bd7bb5eafb36b278eed245c7269307143a1a1e9e5a1a4bce40585a7822aa3aa3ca02a42a245a22a4208d10784040fa580021141208507225ee8c54a0304e22ac40d4da2d234d9b8a95dafed65edf55ece6d6678d88d55048a38d2e89c199df9cd3773fedf770477b93ef525881c9514922416078105428b6dcffddce8bbcd15ff6b70f2712192e9c4c787b78c1fdbba65ece181fce09eb49b19884d14b4fc8dc585a5db173ea8bd77a6bebef2ea8e75dd387dfaff007f72dac98d96c79fbde72353d389ac2ad6fd05516f2fd1891a784e923e6f8062df76520ce8dbefcfff6deeedd9e72efca4f5fa5dc107a6e5b6bdbbee7d69627ce2c8f5daac5c0f96510e482510b2fb8e3560b445d904e3854f90b1a5da9f2fbefc4c6d69edc4d5d3d83b2cb5a9f40927b777d7815f96478a8f5d5e98918169a23c81e309942750ae403aa2bb88006d63561b0b04a6999e9c38fc60b579abf2de6c78f53fc0fb9e14627468ecf989b1892fbfb5f82789d29b50c7eddd3d8972bad0ae74b016dafe063b872693fb764d3de44dbdf3ca3baf06d54df0c4bda9ddbb77eeffd1cdda9b7d91eda05c81e34a94db55eb24ba7da904882ed01a90383cba679a63079e25e76e4ddfa85f1c2cdedff8fd8d99c8c8a927a1901bfa6268dbc50d7f0d015d550284bcd304ca05e5769f85849497e1f1fbbfcdf4e1efe13a0972892decccdf77c4f5e43880345a25fbd2b9476a1b8ba2b7436cef13580b596f90dd430f60b5446bb0c6d29f28f2d4033fe6e8e4d710488c311863d89edd9f4dc9ecc3001248b98ebbb7d1aa83b15803982e6038bb8be30f9ee2f8677fcdfea147d181613039c6d3874f7268c717904211c7315a6bb4d6a44501b191df09e0488b0322e78701ca03632cc608f6940f71fcc8cf28f58f01f0d4a75fe2e41bcf7074df7146721f05406b4d18868461c8fcea355e7efb17ac351afd008e15586da2182394d516ab4118876307bf49a97ffb668da7dd7ebe7ae8c5cdbeb5964ea743bbd3e6ef95d73871ee5b64138318a383ee5148a2d886cbae4aa0638b8e2c4110f2fd334f70f1c60cd69affb2abd69a76bbcd46b3c12b977fc54fcf7d838df63a5869631dcd0348694cabe3b766fb32fd186dd1b1c54496d5fa122f9c99e62fd7fe401004c4714c1445f8be4fb3d9a4565fe637e75fe0d45fbf8bef77c0480432eaf8cdf3006a710e333c25338385c2d1466b4d186d370dd0095b5caa9ca5901ea690da461004b4db6d56ea8b9c38f71c33577e4b14c6e8c8924de711425cae37ea3f5cba647d0550bc277a3fd3d7f7b9649f53eeb47d4c6c7b26b0046187b9ca59725e8981c4080bb50a2fce7c9db9caebc491c64416e5284ac511535dae7ea715f9e757e67ace6b2ed84e7a7bb85a2e953f8f1b7851a4d151b7f48c81300ab85499210c224ecffe804af51a3a3618036e423252de6a1b6badd7fe555d7bfead9336d8b474d842aedc8cdecd6cf5dd916dc39f51a9582134d674ad6bb545479a7f2e5ea4e9af2344373bd2599772a96cdb8df8fabb6f56a7affd4e2fdd291ad58b4e4777f096af8757647f3b2c958b93fd855442260d2a014e42e226156e4ae1a515a9ac43be90259f2bdad5dbcdb92b33d5a72b67cdadaeb5d0801577c04012c808416edb7deaa11d07f35f29ede8dbef65848bd2c21883402090e840d9c66a509bbf5cffe3ad0bfea9e607f626b00134011fd0e243f1e90009200de4bd8c18cd8d8abd5b3e963898ce3ba38e27333ab63a0ef4facacdf06a7d3efe476bc95eb7962ab0067480008801233ef42711bdec5080dbdb4112480109e5e11a8db59ab8a7aad36b2110f58ea09734f06ffee87b7e510400250000000049454e44ae426082', 'image/jpeg'),
(2, 'a2', 'text/plain')
ON CONFLICT (id) DO UPDATE SET mimetype=excluded.mimetype, data=excluded.data;

UPDATE mediafile_data SET data = 'a2', mimetype='text/plain' WHERE id=2;
UPDATE mediafile_data SET data = '\x89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b000000017352474200aece1ce900000006624b474400ff00ff00ffa0bda793000000097048597300000dd700000dd70142289b780000000774494d4507da0a070821340b2e051f000005364944415438cb8d955b6c5c471dc67f3373ced99bd7bb5eafb36b278eed245c7269307143a1a1e9e5a1a4bce40585a7822aa3aa3ca02a42a245a22a4208d10784040fa580021141208507225ee8c54a0304e22ac40d4da2d234d9b8a95dafed65edf55ece6d6678d88d55048a38d2e89c199df9cd3773fedf770477b93ef525881c9514922416078105428b6dcffddce8bbcd15ff6b70f2712192e9c4c787b78c1fdbba65ece181fce09eb49b19884d14b4fc8dc585a5db173ea8bd77a6bebef2ea8e75dd387dfaff007f72dac98d96c79fbde72353d389ac2ad6fd05516f2fd1891a784e923e6f8062df76520ce8dbefcfff6deeedd9e72efca4f5fa5dc107a6e5b6bdbbee7d69627ce2c8f5daac5c0f96510e482510b2fb8e3560b445d904e3854f90b1a5da9f2fbefc4c6d69edc4d5d3d83b2cb5a9f40927b777d7815f96478a8f5d5e98918169a23c81e309942750ae403aa2bb88006d63561b0b04a6999e9c38fc60b579abf2de6c78f53fc0fb9e14627468ecf989b1892fbfb5f82789d29b50c7eddd3d8972bad0ae74b016dafe063b872693fb764d3de44dbdf3ca3baf06d54df0c4bda9ddbb77eeffd1cdda9b7d91eda05c81e34a94db55eb24ba7da904882ed01a90383cba679a63079e25e76e4ddfa85f1c2cdedff8fd8d99c8c8a927a1901bfa6268dbc50d7f0d015d550284bcd304ca05e5769f85849497e1f1fbbfcdf4e1efe13a0972892decccdf77c4f5e43880345a25fbd2b9476a1b8ba2b7436cef13580b596f90dd430f60b5446bb0c6d29f28f2d4033fe6e8e4d710488c311863d89edd9f4dc9ecc3001248b98ebbb7d1aa83b15803982e6038bb8be30f9ee2f8677fcdfea147d181613039c6d3874f7268c717904211c7315a6bb4d6a44501b191df09e0488b0322e78701ca03632cc608f6940f71fcc8cf28f58f01f0d4a75fe2e41bcf7074df7146721f05406b4d18868461c8fcea355e7efb17ac351afd008e15586da2182394d516ab4118876307bf49a97ffb668da7dd7ebe7ae8c5cdbeb5964ea743bbd3e6ef95d73871ee5b64138318a383ee5148a2d886cbae4aa0638b8e2c4110f2fd334f70f1c60cd69affb2abd69a76bbcd46b3c12b977fc54fcf7d838df63a5869631dcd0348694cabe3b766fb32fd186dd1b1c54496d5fa122f9c99e62fd7fe401004c4714c1445f8be4fb3d9a4565fe637e75fe0d45fbf8bef77c0480432eaf8cdf3006a710e333c25338385c2d1466b4d186d370dd0095b5caa9ca5901ea690da461004b4db6d56ea8b9c38f71c33577e4b14c6e8c8924de711425cae37ea3f5cba647d0550bc277a3fd3d7f7b9649f53eeb47d4c6c7b26b0046187b9ca59725e8981c4080bb50a2fce7c9db9caebc491c64416e5284ac511535dae7ea715f9e757e67ace6b2ed84e7a7bb85a2e953f8f1b7851a4d151b7f48c81300ab85499210c224ecffe804af51a3a3618036e423252de6a1b6badd7fe555d7bfead9336d8b474d842aedc8cdecd6cf5dd916dc39f51a9582134d674ad6bb545479a7f2e5ea4e9af2344373bd2599772a96cdb8df8fabb6f56a7affd4e2fdd291ad58b4e4777f096af8757647f3b2c958b93fd855442260d2a014e42e226156e4ae1a515a9ac43be90259f2bdad5dbcdb92b33d5a72b67cdadaeb5d0801577c04012c808416edb7deaa11d07f35f29ede8dbef65848bd2c21883402090e840d9c66a509bbf5cffe3ad0bfea9e607f626b00134011fd0e243f1e90009200de4bd8c18cd8d8abd5b3e963898ce3ba38e27333ab63a0ef4facacdf06a7d3efe476bc95eb7962ab0067480008801233ef42711bdec5080dbdb4112480109e5e11a8db59ab8a7aad36b2110f58ea09734f06ffee87b7e510400250000000049454e44ae426082',
mimetype ='image/png' WHERE id=3;
INSERT INTO resource_data VALUES
(1, '\x89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b000000017352474200aece1ce900000006624b474400ff00ff00ffa0bda793000000097048597300000dd700000dd70142289b780000000774494d4507da0a070821340b2e051f000005364944415438cb8d955b6c5c471dc67f3373ced99bd7bb5eafb36b278eed245c7269307143a1a1e9e5a1a4bce40585a7822aa3aa3ca02a42a245a22a4208d10784040fa580021141208507225ee8c54a0304e22ac40d4da2d234d9b8a95dafed65edf55ece6d6678d88d55048a38d2e89c199df9cd3773fedf770477b93ef525881c9514922416078105428b6dcffddce8bbcd15ff6b70f2712192e9c4c787b78c1fdbba65ece181fce09eb49b19884d14b4fc8dc585a5db173ea8bd77a6bebef2ea8e75dd387dfaff007f72dac98d96c79fbde72353d389ac2ad6fd05516f2fd1891a784e923e6f8062df76520ce8dbefcfff6deeedd9e72efca4f5fa5dc107a6e5b6bdbbee7d69627ce2c8f5daac5c0f96510e482510b2fb8e3560b445d904e3854f90b1a5da9f2fbefc4c6d69edc4d5d3d83b2cb5a9f40927b777d7815f96478a8f5d5e98918169a23c81e309942750ae403aa2bb88006d63561b0b04a6999e9c38fc60b579abf2de6c78f53fc0fb9e14627468ecf989b1892fbfb5f82789d29b50c7eddd3d8972bad0ae74b016dafe063b872693fb764d3de44dbdf3ca3baf06d54df0c4bda9ddbb77eeffd1cdda9b7d91eda05c81e34a94db55eb24ba7da904882ed01a90383cba679a63079e25e76e4ddfa85f1c2cdedff8fd8d99c8c8a927a1901bfa6268dbc50d7f0d015d550284bcd304ca05e5769f85849497e1f1fbbfcdf4e1efe13a0972892decccdf77c4f5e43880345a25fbd2b9476a1b8ba2b7436cef13580b596f90dd430f60b5446bb0c6d29f28f2d4033fe6e8e4d710488c311863d89edd9f4dc9ecc3001248b98ebbb7d1aa83b15803982e6038bb8be30f9ee2f8677fcdfea147d181613039c6d3874f7268c717904211c7315a6bb4d6a44501b191df09e0488b0322e78701ca03632cc608f6940f71fcc8cf28f58f01f0d4a75fe2e41bcf7074df7146721f05406b4d18868461c8fcea355e7efb17ac351afd008e15586da2182394d516ab4118876307bf49a97ffb668da7dd7ebe7ae8c5cdbeb5964ea743bbd3e6ef95d73871ee5b64138318a383ee5148a2d886cbae4aa0638b8e2c4110f2fd334f70f1c60cd69affb2abd69a76bbcd46b3c12b977fc54fcf7d838df63a5869631dcd0348694cabe3b766fb32fd186dd1b1c54496d5fa122f9c99e62fd7fe401004c4714c1445f8be4fb3d9a4565fe637e75fe0d45fbf8bef77c0480432eaf8cdf3006a710e333c25338385c2d1466b4d186d370dd0095b5caa9ca5901ea690da461004b4db6d56ea8b9c38f71c33577e4b14c6e8c8924de711425cae37ea3f5cba647d0550bc277a3fd3d7f7b9649f53eeb47d4c6c7b26b0046187b9ca59725e8981c4080bb50a2fce7c9db9caebc491c64416e5284ac511535dae7ea715f9e757e67ace6b2ed84e7a7bb85a2e953f8f1b7851a4d151b7f48c81300ab85499210c224ecffe804af51a3a3618036e423252de6a1b6badd7fe555d7bfead9336d8b474d842aedc8cdecd6cf5dd916dc39f51a9582134d674ad6bb545479a7f2e5ea4e9af2344373bd2599772a96cdb8df8fabb6f56a7affd4e2fdd291ad58b4e4777f096af8757647f3b2c958b93fd855442260d2a014e42e226156e4ae1a515a9ac43be90259f2bdad5dbcdb92b33d5a72b67cdadaeb5d0801577c04012c808416edb7deaa11d07f35f29ede8dbef65848bd2c21883402090e840d9c66a509bbf5cffe3ad0bfea9e607f626b00134011fd0e243f1e90009200de4bd8c18cd8d8abd5b3e963898ce3ba38e27333ab63a0ef4facacdf06a7d3efe476bc95eb7962ab0067480008801233ef42711bdec5080dbdb4112480109e5e11a8db59ab8a7aad36b2110f58ea09734f06ffee87b7e510400250000000049454e44ae426082', 'image/jpeg')
ON CONFLICT (id) DO UPDATE SET mimetype=excluded.mimetype, data=excluded.data;
27 changes: 15 additions & 12 deletions tests/dummy_presenter/dummy_presenter.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,34 +9,37 @@
@app.route("/system/presenter", methods=["POST"])
def dummy_presenter():
app.logger.debug(f"dummy_presenter gets: {request.json}")
mediafile_id = request.json[0]["data"]["mediafile_id"]
if request.json[0]["presenter"] == "check_mediafile_id":
file_id = request.json[0]["data"]["mediafile_id"]
elif request.json[0]["presenter"] == "check_resource_id":
file_id = request.json[0]["data"]["resource_id"]

# Valid response from presenter, but not found in DB
if mediafile_id == 1:
if file_id == 1:
return jsonify([{"ok": True, "filename": "Does not exist"}])

# OK-cases for dummy data
if mediafile_id == 2:
if file_id == 2:
return jsonify([{"ok": True, "filename": "A.txt"}])
if mediafile_id == 3:
if file_id == 3:
return jsonify([{"ok": True, "filename": "in.jpg"}])

# OK-cases for uploaded data
if mediafile_id in (4, 5, 6, 7):
return jsonify([{"ok": True, "filename": str(mediafile_id)}])
if file_id in (4, 5, 6, 7):
return jsonify([{"ok": True, "filename": str(file_id)}])

# invalid responses
if mediafile_id == 10:
if file_id == 10:
return jsonify([None])
if mediafile_id == 11:
if file_id == 11:
return "some text"
if mediafile_id == 12:
if file_id == 12:
return "An error", 500
if mediafile_id == 13:
if file_id == 13:
return {"ok": False}
if mediafile_id == 14:
if file_id == 14:
return jsonify([{"ok": True}])

# not found or no perms
if mediafile_id == 20:
if file_id == 20:
return jsonify([{"ok": False}])
32 changes: 32 additions & 0 deletions tests/test_get_resource.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Tests for the openslides media service
import requests

GET_URL = "http://media:9006/system/media/get_resource/"


def test_positiv():
# wait the service to start
req = requests.get(GET_URL + "1")
assert req.status_code == 200
assert len(req.content) == 1462
assert type(req.content) == bytes
assert "image/jpeg" in req.headers.get("Content-Type")


def test_not_found():
req = requests.get(GET_URL + "2")
assert req.status_code == 500
assert "message" in req.json()


def test_invalid_responses():
for i in (10, 11, 12, 13, 14):
req = requests.get(GET_URL + str(i))
assert req.status_code == 500
assert "message" in req.json()


def test_not_ok_from_presenter():
req = requests.get(GET_URL + "20")
assert req.status_code == 404
assert "message" in req.json()

0 comments on commit 6db3ecb

Please sign in to comment.