diff options
Diffstat (limited to 'api/opendc')
27 files changed, 370 insertions, 328 deletions
diff --git a/api/opendc/api/v2/portfolios/portfolioId/endpoint.py b/api/opendc/api/v2/portfolios/portfolioId/endpoint.py index c0ca64e0..0ba61a13 100644 --- a/api/opendc/api/v2/portfolios/portfolioId/endpoint.py +++ b/api/opendc/api/v2/portfolios/portfolioId/endpoint.py @@ -54,10 +54,12 @@ def DELETE(request): portfolio.check_exists() portfolio.check_user_access(request.google_id, True) + portfolio_id = portfolio.get_id() + project = Project.from_id(portfolio.obj['projectId']) project.check_exists() - if request.params_path['portfolioId'] in project.obj['portfolioIds']: - project.obj['portfolioIds'].remove(request.params_path['portfolioId']) + if portfolio_id in project.obj['portfolioIds']: + project.obj['portfolioIds'].remove(portfolio_id) project.update() old_object = portfolio.delete() diff --git a/api/opendc/api/v2/portfolios/portfolioId/scenarios/endpoint.py b/api/opendc/api/v2/portfolios/portfolioId/scenarios/endpoint.py index ca1db36a..fc2cab16 100644 --- a/api/opendc/api/v2/portfolios/portfolioId/scenarios/endpoint.py +++ b/api/opendc/api/v2/portfolios/portfolioId/scenarios/endpoint.py @@ -32,7 +32,7 @@ def POST(request): scenario = Scenario(request.params_body['scenario']) - scenario.set_property('portfolioId', request.params_path['portfolioId']) + scenario.set_property('portfolioId', portfolio.get_id()) scenario.set_property('simulation', {'state': 'QUEUED'}) scenario.insert() diff --git a/api/opendc/api/v2/portfolios/portfolioId/scenarios/test_endpoint.py b/api/opendc/api/v2/portfolios/portfolioId/scenarios/test_endpoint.py index 329e68e8..84ad2830 100644 --- a/api/opendc/api/v2/portfolios/portfolioId/scenarios/test_endpoint.py +++ b/api/opendc/api/v2/portfolios/portfolioId/scenarios/test_endpoint.py @@ -1,5 +1,7 @@ from opendc.util.database import DB +test_id = 24 * '1' + def test_add_scenario_missing_parameter(client): assert '400' in client.post('/api/v2/portfolios/1/scenarios').status @@ -7,16 +9,16 @@ def test_add_scenario_missing_parameter(client): def test_add_scenario_non_existing_portfolio(client, mocker): mocker.patch.object(DB, 'fetch_one', return_value=None) - assert '404' in client.post('/api/v2/portfolios/1/scenarios', + assert '404' in client.post(f'/api/v2/portfolios/{test_id}/scenarios', json={ 'scenario': { 'name': 'test', 'trace': { - 'traceId': '1', + 'traceId': test_id, 'loadSamplingFraction': 1.0, }, 'topology': { - 'topologyId': '1', + 'topologyId': test_id, }, 'operational': { 'failuresEnabled': True, @@ -31,24 +33,24 @@ def test_add_scenario_not_authorized(client, mocker): mocker.patch.object(DB, 'fetch_one', return_value={ - '_id': '1', - 'projectId': '1', - 'portfolioId': '1', + '_id': test_id, + 'projectId': test_id, + 'portfolioId': test_id, 'authorizations': [{ - 'projectId': '1', + 'projectId': test_id, 'authorizationLevel': 'VIEW' }] }) - assert '403' in client.post('/api/v2/portfolios/1/scenarios', + assert '403' in client.post(f'/api/v2/portfolios/{test_id}/scenarios', json={ 'scenario': { 'name': 'test', 'trace': { - 'traceId': '1', + 'traceId': test_id, 'loadSamplingFraction': 1.0, }, 'topology': { - 'topologyId': '1', + 'topologyId': test_id, }, 'operational': { 'failuresEnabled': True, @@ -63,13 +65,13 @@ def test_add_scenario(client, mocker): mocker.patch.object(DB, 'fetch_one', return_value={ - '_id': '1', - 'projectId': '1', - 'portfolioId': '1', - 'portfolioIds': ['1'], - 'scenarioIds': ['1'], + '_id': test_id, + 'projectId': test_id, + 'portfolioId': test_id, + 'portfolioIds': [test_id], + 'scenarioIds': [test_id], 'authorizations': [{ - 'projectId': '1', + 'projectId': test_id, 'authorizationLevel': 'EDIT' }], 'simulation': { @@ -79,37 +81,37 @@ def test_add_scenario(client, mocker): mocker.patch.object(DB, 'insert', return_value={ - '_id': '1', + '_id': test_id, 'name': 'test', 'trace': { - 'traceId': '1', + 'traceId': test_id, 'loadSamplingFraction': 1.0, }, 'topology': { - 'topologyId': '1', + 'topologyId': test_id, }, 'operational': { 'failuresEnabled': True, 'performanceInterferenceEnabled': False, 'schedulerName': 'DEFAULT', }, - 'portfolioId': '1', + 'portfolioId': test_id, 'simulationState': { 'state': 'QUEUED', }, }) mocker.patch.object(DB, 'update', return_value=None) res = client.post( - '/api/v2/portfolios/1/scenarios', + f'/api/v2/portfolios/{test_id}/scenarios', json={ 'scenario': { 'name': 'test', 'trace': { - 'traceId': '1', + 'traceId': test_id, 'loadSamplingFraction': 1.0, }, 'topology': { - 'topologyId': '1', + 'topologyId': test_id, }, 'operational': { 'failuresEnabled': True, diff --git a/api/opendc/api/v2/portfolios/portfolioId/test_endpoint.py b/api/opendc/api/v2/portfolios/portfolioId/test_endpoint.py index 7ac346d4..2d9d8d13 100644 --- a/api/opendc/api/v2/portfolios/portfolioId/test_endpoint.py +++ b/api/opendc/api/v2/portfolios/portfolioId/test_endpoint.py @@ -1,14 +1,17 @@ from opendc.util.database import DB +test_id = 24 * '1' +test_id_2 = 24 * '2' + def test_get_portfolio_non_existing(client, mocker): mocker.patch.object(DB, 'fetch_one', return_value=None) - assert '404' in client.get('/api/v2/portfolios/1').status + assert '404' in client.get(f'/api/v2/portfolios/{test_id}').status def test_get_portfolio_no_authorizations(client, mocker): - mocker.patch.object(DB, 'fetch_one', return_value={'projectId': '1', 'authorizations': []}) - res = client.get('/api/v2/portfolios/1') + mocker.patch.object(DB, 'fetch_one', return_value={'projectId': test_id, 'authorizations': []}) + res = client.get(f'/api/v2/portfolios/{test_id}') assert '403' in res.status @@ -16,14 +19,14 @@ def test_get_portfolio_not_authorized(client, mocker): mocker.patch.object(DB, 'fetch_one', return_value={ - 'projectId': '1', - '_id': '1', + 'projectId': test_id, + '_id': test_id, 'authorizations': [{ - 'projectId': '2', + 'projectId': test_id_2, 'authorizationLevel': 'OWN' }] }) - res = client.get('/api/v2/portfolios/1') + res = client.get(f'/api/v2/portfolios/{test_id}') assert '403' in res.status @@ -31,24 +34,24 @@ def test_get_portfolio(client, mocker): mocker.patch.object(DB, 'fetch_one', return_value={ - 'projectId': '1', - '_id': '1', + 'projectId': test_id, + '_id': test_id, 'authorizations': [{ - 'projectId': '1', + 'projectId': test_id, 'authorizationLevel': 'EDIT' }] }) - res = client.get('/api/v2/portfolios/1') + res = client.get(f'/api/v2/portfolios/{test_id}') assert '200' in res.status def test_update_portfolio_missing_parameter(client): - assert '400' in client.put('/api/v2/portfolios/1').status + assert '400' in client.put(f'/api/v2/portfolios/{test_id}').status def test_update_portfolio_non_existing(client, mocker): mocker.patch.object(DB, 'fetch_one', return_value=None) - assert '404' in client.put('/api/v2/portfolios/1', json={ + assert '404' in client.put(f'/api/v2/portfolios/{test_id}', json={ 'portfolio': { 'name': 'test', 'targets': { @@ -63,15 +66,15 @@ def test_update_portfolio_not_authorized(client, mocker): mocker.patch.object(DB, 'fetch_one', return_value={ - '_id': '1', - 'projectId': '1', + '_id': test_id, + 'projectId': test_id, 'authorizations': [{ - 'projectId': '1', + 'projectId': test_id, 'authorizationLevel': 'VIEW' }] }) mocker.patch.object(DB, 'update', return_value={}) - assert '403' in client.put('/api/v2/portfolios/1', json={ + assert '403' in client.put(f'/api/v2/portfolios/{test_id}', json={ 'portfolio': { 'name': 'test', 'targets': { @@ -86,10 +89,10 @@ def test_update_portfolio(client, mocker): mocker.patch.object(DB, 'fetch_one', return_value={ - '_id': '1', - 'projectId': '1', + '_id': test_id, + 'projectId': test_id, 'authorizations': [{ - 'projectId': '1', + 'projectId': test_id, 'authorizationLevel': 'OWN' }], 'targets': { @@ -99,7 +102,7 @@ def test_update_portfolio(client, mocker): }) mocker.patch.object(DB, 'update', return_value={}) - res = client.put('/api/v2/portfolios/1', json={'portfolio': { + res = client.put(f'/api/v2/portfolios/{test_id}', json={'portfolio': { 'name': 'test', 'targets': { 'enabledMetrics': ['test'], @@ -111,39 +114,39 @@ def test_update_portfolio(client, mocker): def test_delete_project_non_existing(client, mocker): mocker.patch.object(DB, 'fetch_one', return_value=None) - assert '404' in client.delete('/api/v2/portfolios/1').status + assert '404' in client.delete(f'/api/v2/portfolios/{test_id}').status def test_delete_project_different_user(client, mocker): mocker.patch.object(DB, 'fetch_one', return_value={ - '_id': '1', - 'projectId': '1', + '_id': test_id, + 'projectId': test_id, 'googleId': 'other_test', 'authorizations': [{ - 'projectId': '1', + 'projectId': test_id, 'authorizationLevel': 'VIEW' }] }) mocker.patch.object(DB, 'delete_one', return_value=None) - assert '403' in client.delete('/api/v2/portfolios/1').status + assert '403' in client.delete(f'/api/v2/portfolios/{test_id}').status def test_delete_project(client, mocker): mocker.patch.object(DB, 'fetch_one', return_value={ - '_id': '1', - 'projectId': '1', + '_id': test_id, + 'projectId': test_id, 'googleId': 'test', - 'portfolioIds': ['1'], + 'portfolioIds': [test_id], 'authorizations': [{ - 'projectId': '1', + 'projectId': test_id, 'authorizationLevel': 'OWN' }] }) mocker.patch.object(DB, 'delete_one', return_value={}) mocker.patch.object(DB, 'update', return_value=None) - res = client.delete('/api/v2/portfolios/1') + res = client.delete(f'/api/v2/portfolios/{test_id}') assert '200' in res.status diff --git a/api/opendc/api/v2/prefabs/authorizations/endpoint.py b/api/opendc/api/v2/prefabs/authorizations/endpoint.py index b487b9cc..0d9ad5cd 100644 --- a/api/opendc/api/v2/prefabs/authorizations/endpoint.py +++ b/api/opendc/api/v2/prefabs/authorizations/endpoint.py @@ -7,13 +7,12 @@ from opendc.util.rest import Response def GET(request): """Return all prefabs the user is authorized to access""" - user = User.from_id(request.google_id) + user = User.from_google_id(request.google_id) user.check_exists() - - own_prefabs = DB.fetch_all({'authorId' : user.get_id()}, Prefab.collection_name) - public_prefabs = DB.fetch_all({'visibility' : 'public'}, Prefab.collection_name) + own_prefabs = DB.fetch_all({'authorId': user.get_id()}, Prefab.collection_name) + public_prefabs = DB.fetch_all({'visibility': 'public'}, Prefab.collection_name) authorizations = {"authorizations": []} diff --git a/api/opendc/api/v2/prefabs/authorizations/test_endpoint.py b/api/opendc/api/v2/prefabs/authorizations/test_endpoint.py index 38401045..6ca0448e 100644 --- a/api/opendc/api/v2/prefabs/authorizations/test_endpoint.py +++ b/api/opendc/api/v2/prefabs/authorizations/test_endpoint.py @@ -1,68 +1,71 @@ from opendc.util.database import DB from unittest.mock import Mock +test_id = 24 * '1' + + def test_get_authorizations(client, mocker): DB.fetch_all = Mock() - mocker.patch.object(DB, 'fetch_one', return_value={'_id': '1'}) + mocker.patch.object(DB, 'fetch_one', return_value={'_id': test_id}) DB.fetch_all.side_effect = [ [{ - '_id': '1', + '_id': test_id, 'datetimeCreated': '000', 'datetimeLastEdited': '000', - 'authorId': 1, + 'authorId': test_id, 'visibility' : 'private' }, { - '_id': '2', + '_id': '2' * 24, 'datetimeCreated': '000', 'datetimeLastEdited': '000', - 'authorId': 1, + 'authorId': test_id, 'visibility' : 'private' }, { - '_id': '3', + '_id': '3' * 24, 'datetimeCreated': '000', 'datetimeLastEdited': '000', - 'authorId': 1, + 'authorId': test_id, 'visibility' : 'public' }, { - '_id': '4', + '_id': '4' * 24, 'datetimeCreated': '000', 'datetimeLastEdited': '000', - 'authorId': 1, + 'authorId': test_id, 'visibility' : 'public' }], [{ - '_id': '5', + '_id': '5' * 24, 'datetimeCreated': '000', 'datetimeLastEdited': '000', - 'authorId': 2, + 'authorId': '2' * 24, 'visibility' : 'public' }, { - '_id': '6', + '_id': '6' * 24, 'datetimeCreated': '000', 'datetimeLastEdited': '000', - 'authorId': 2, + 'authorId': '2' * 24, 'visibility' : 'public' }, { - '_id': '7', + '_id': '7' * 24, 'datetimeCreated': '000', 'datetimeLastEdited': '000', - 'authorId': 2, + 'authorId': '2' * 24, 'visibility' : 'public' }, { - '_id': '8', + '_id': '8' * 24, 'datetimeCreated': '000', 'datetimeLastEdited': '000', - 'authorId': 2, + 'authorId': '2' * 24, 'visibility' : 'public' }] ] - mocker.patch.object(DB, 'fetch_one', return_value={'_id': '1'}) + mocker.patch.object(DB, 'fetch_one', return_value={'_id': test_id}) res = client.get('/api/v2/prefabs/authorizations') assert '200' in res.status diff --git a/api/opendc/api/v2/prefabs/prefabId/test_endpoint.py b/api/opendc/api/v2/prefabs/prefabId/test_endpoint.py index b25c881d..28a71861 100644 --- a/api/opendc/api/v2/prefabs/prefabId/test_endpoint.py +++ b/api/opendc/api/v2/prefabs/prefabId/test_endpoint.py @@ -1,140 +1,145 @@ from opendc.util.database import DB from unittest.mock import Mock +test_id = 24 * '1' +test_id_2 = 24 * '2' + def test_get_prefab_non_existing(client, mocker): mocker.patch.object(DB, 'fetch_one', return_value=None) - assert '404' in client.get('/api/v2/prefabs/1').status + assert '404' in client.get(f'/api/v2/prefabs/{test_id}').status + def test_get_private_prefab_not_authorized(client, mocker): DB.fetch_one = Mock() DB.fetch_one.side_effect = [{ - '_id': '1', - 'name': 'test prefab', - 'authorId': '2', - 'visibility': 'private', - 'rack': {} - }, - { - '_id': '1' - } - ] - res = client.get('/api/v2/prefabs/1') + '_id': test_id, + 'name': 'test prefab', + 'authorId': test_id_2, + 'visibility': 'private', + 'rack': {} + }, + { + '_id': test_id + } + ] + res = client.get(f'/api/v2/prefabs/{test_id}') assert '403' in res.status def test_get_private_prefab(client, mocker): DB.fetch_one = Mock() DB.fetch_one.side_effect = [{ - '_id': '1', - 'name': 'test prefab', - 'authorId': '1', - 'visibility': 'private', - 'rack': {} - }, - { - '_id': '1' - } - ] - res = client.get('/api/v2/prefabs/1') + '_id': test_id, + 'name': 'test prefab', + 'authorId': test_id, + 'visibility': 'private', + 'rack': {} + }, + { + '_id': test_id + } + ] + res = client.get(f'/api/v2/prefabs/{test_id}') assert '200' in res.status + def test_get_public_prefab(client, mocker): DB.fetch_one = Mock() DB.fetch_one.side_effect = [{ - '_id': '1', - 'name': 'test prefab', - 'authorId': '2', - 'visibility': 'public', - 'rack': {} - }, - { - '_id': '1' - } - ] - res = client.get('/api/v2/prefabs/1') + '_id': test_id, + 'name': 'test prefab', + 'authorId': test_id_2, + 'visibility': 'public', + 'rack': {} + }, + { + '_id': test_id + } + ] + res = client.get(f'/api/v2/prefabs/{test_id}') assert '200' in res.status def test_update_prefab_missing_parameter(client): - assert '400' in client.put('/api/v2/prefabs/1').status + assert '400' in client.put(f'/api/v2/prefabs/{test_id}').status def test_update_prefab_non_existing(client, mocker): mocker.patch.object(DB, 'fetch_one', return_value=None) - assert '404' in client.put('/api/v2/prefabs/1', json={'prefab': {'name': 'S'}}).status + assert '404' in client.put(f'/api/v2/prefabs/{test_id}', json={'prefab': {'name': 'S'}}).status def test_update_prefab_not_authorized(client, mocker): DB.fetch_one = Mock() DB.fetch_one.side_effect = [{ - '_id': '1', - 'name': 'test prefab', - 'authorId': '2', - 'visibility': 'private', - 'rack': {} - }, - { - '_id': '1' - } - ] + '_id': test_id, + 'name': 'test prefab', + 'authorId': test_id_2, + 'visibility': 'private', + 'rack': {} + }, + { + '_id': test_id + } + ] mocker.patch.object(DB, 'update', return_value={}) - assert '403' in client.put('/api/v2/prefabs/1', json={'prefab': {'name': 'test prefab', 'rack' : {}}}).status + assert '403' in client.put(f'/api/v2/prefabs/{test_id}', json={'prefab': {'name': 'test prefab', 'rack': {}}}).status def test_update_prefab(client, mocker): DB.fetch_one = Mock() DB.fetch_one.side_effect = [{ - '_id': '1', - 'name': 'test prefab', - 'authorId': '1', - 'visibility': 'private', - 'rack': {} - }, - { - '_id': '1' - } - ] + '_id': test_id, + 'name': 'test prefab', + 'authorId': test_id, + 'visibility': 'private', + 'rack': {} + }, + { + '_id': test_id + } + ] mocker.patch.object(DB, 'update', return_value={}) - res = client.put('/api/v2/prefabs/1', json={'prefab': {'name': 'test prefab', 'rack' : {}}}) + res = client.put(f'/api/v2/prefabs/{test_id}', json={'prefab': {'name': 'test prefab', 'rack': {}}}) assert '200' in res.status def test_delete_prefab_non_existing(client, mocker): mocker.patch.object(DB, 'fetch_one', return_value=None) - assert '404' in client.delete('/api/v2/prefabs/1').status + assert '404' in client.delete(f'/api/v2/prefabs/{test_id}').status def test_delete_prefab_different_user(client, mocker): DB.fetch_one = Mock() DB.fetch_one.side_effect = [{ - '_id': '1', - 'name': 'test prefab', - 'authorId': '2', - 'visibility': 'private', - 'rack': {} - }, - { - '_id': '1' - } - ] + '_id': test_id, + 'name': 'test prefab', + 'authorId': test_id_2, + 'visibility': 'private', + 'rack': {} + }, + { + '_id': test_id + } + ] mocker.patch.object(DB, 'delete_one', return_value=None) - assert '403' in client.delete('/api/v2/prefabs/1').status + assert '403' in client.delete(f'/api/v2/prefabs/{test_id}').status def test_delete_prefab(client, mocker): DB.fetch_one = Mock() DB.fetch_one.side_effect = [{ - '_id': '1', - 'name': 'test prefab', - 'authorId': '1', - 'visibility': 'private', - 'rack': {} - }, - { - '_id': '1' - } - ] + '_id': test_id, + 'name': 'test prefab', + 'authorId': test_id, + 'visibility': 'private', + 'rack': {} + }, + { + '_id': test_id + } + ] mocker.patch.object(DB, 'delete_one', return_value={'prefab': {'name': 'name'}}) - res = client.delete('/api/v2/prefabs/1') + res = client.delete(f'/api/v2/prefabs/{test_id}') assert '200' in res.status diff --git a/api/opendc/api/v2/prefabs/test_endpoint.py b/api/opendc/api/v2/prefabs/test_endpoint.py index 47029579..affa24c9 100644 --- a/api/opendc/api/v2/prefabs/test_endpoint.py +++ b/api/opendc/api/v2/prefabs/test_endpoint.py @@ -1,19 +1,21 @@ from opendc.util.database import DB +test_id = 24 * '1' + def test_add_prefab_missing_parameter(client): assert '400' in client.post('/api/v2/prefabs').status def test_add_prefab(client, mocker): - mocker.patch.object(DB, 'fetch_one', return_value={'_id': '1', 'authorizations': []}) + mocker.patch.object(DB, 'fetch_one', return_value={'_id': test_id, 'authorizations': []}) mocker.patch.object(DB, 'insert', return_value={ - '_id': '1', + '_id': test_id, 'datetimeCreated': '000', 'datetimeLastEdited': '000', - 'authorId': 1 + 'authorId': test_id }) res = client.post('/api/v2/prefabs', json={'prefab': {'name': 'test prefab'}}) assert 'datetimeCreated' in res.json['content'] diff --git a/api/opendc/api/v2/projects/projectId/authorizations/test_endpoint.py b/api/opendc/api/v2/projects/projectId/authorizations/test_endpoint.py index c3bbc093..d2d7cba1 100644 --- a/api/opendc/api/v2/projects/projectId/authorizations/test_endpoint.py +++ b/api/opendc/api/v2/projects/projectId/authorizations/test_endpoint.py @@ -1,25 +1,28 @@ from opendc.util.database import DB +test_id = 24 * '1' +test_id_2 = 24 * '2' + def test_get_authorizations_non_existing(client, mocker): mocker.patch.object(DB, 'fetch_one', return_value=None) mocker.patch.object(DB, 'fetch_all', return_value=None) - assert '404' in client.get('/api/v2/projects/1/authorizations').status + assert '404' in client.get(f'/api/v2/projects/{test_id}/authorizations').status def test_get_authorizations_not_authorized(client, mocker): mocker.patch.object(DB, 'fetch_one', return_value={ - '_id': '1', + '_id': test_id, 'name': 'test trace', 'authorizations': [{ - 'projectId': '2', + 'projectId': test_id_2, 'authorizationLevel': 'OWN' }] }) mocker.patch.object(DB, 'fetch_all', return_value=[]) - res = client.get('/api/v2/projects/1/authorizations') + res = client.get(f'/api/v2/projects/{test_id}/authorizations') assert '403' in res.status @@ -27,14 +30,14 @@ def test_get_authorizations(client, mocker): mocker.patch.object(DB, 'fetch_one', return_value={ - '_id': '1', + '_id': test_id, 'name': 'test trace', 'authorizations': [{ - 'projectId': '1', + 'projectId': test_id, 'authorizationLevel': 'OWN' }] }) mocker.patch.object(DB, 'fetch_all', return_value=[]) - res = client.get('/api/v2/projects/1/authorizations') + res = client.get(f'/api/v2/projects/{test_id}/authorizations') assert len(res.json['content']) == 0 assert '200' in res.status diff --git a/api/opendc/api/v2/projects/projectId/endpoint.py b/api/opendc/api/v2/projects/projectId/endpoint.py index 77b66d75..caac37ca 100644 --- a/api/opendc/api/v2/projects/projectId/endpoint.py +++ b/api/opendc/api/v2/projects/projectId/endpoint.py @@ -58,7 +58,7 @@ def DELETE(request): user = User.from_google_id(request.google_id) user.obj['authorizations'] = list( - filter(lambda x: str(x['projectId']) != request.params_path['projectId'], user.obj['authorizations'])) + filter(lambda x: x['projectId'] != project.get_id(), user.obj['authorizations'])) user.update() old_object = project.delete() diff --git a/api/opendc/api/v2/projects/projectId/portfolios/endpoint.py b/api/opendc/api/v2/projects/projectId/portfolios/endpoint.py index 0bc65565..2cdb1194 100644 --- a/api/opendc/api/v2/projects/projectId/portfolios/endpoint.py +++ b/api/opendc/api/v2/projects/projectId/portfolios/endpoint.py @@ -24,7 +24,7 @@ def POST(request): portfolio = Portfolio(request.params_body['portfolio']) - portfolio.set_property('projectId', request.params_path['projectId']) + portfolio.set_property('projectId', project.get_id()) portfolio.set_property('scenarioIds', []) portfolio.insert() diff --git a/api/opendc/api/v2/projects/projectId/portfolios/test_endpoint.py b/api/opendc/api/v2/projects/projectId/portfolios/test_endpoint.py index 24416cc3..2a2f777d 100644 --- a/api/opendc/api/v2/projects/projectId/portfolios/test_endpoint.py +++ b/api/opendc/api/v2/projects/projectId/portfolios/test_endpoint.py @@ -1,13 +1,15 @@ from opendc.util.database import DB +test_id = 24 * '1' + def test_add_portfolio_missing_parameter(client): - assert '400' in client.post('/api/v2/projects/1/portfolios').status + assert '400' in client.post(f'/api/v2/projects/{test_id}/portfolios').status def test_add_portfolio_non_existing_project(client, mocker): mocker.patch.object(DB, 'fetch_one', return_value=None) - assert '404' in client.post('/api/v2/projects/1/portfolios', + assert '404' in client.post(f'/api/v2/projects/{test_id}/portfolios', json={ 'portfolio': { 'name': 'test', @@ -23,14 +25,14 @@ def test_add_portfolio_not_authorized(client, mocker): mocker.patch.object(DB, 'fetch_one', return_value={ - '_id': '1', - 'projectId': '1', + '_id': test_id, + 'projectId': test_id, 'authorizations': [{ - 'projectId': '1', + 'projectId': test_id, 'authorizationLevel': 'VIEW' }] }) - assert '403' in client.post('/api/v2/projects/1/portfolios', + assert '403' in client.post(f'/api/v2/projects/{test_id}/portfolios', json={ 'portfolio': { 'name': 'test', @@ -46,29 +48,29 @@ def test_add_portfolio(client, mocker): mocker.patch.object(DB, 'fetch_one', return_value={ - '_id': '1', - 'projectId': '1', - 'portfolioIds': ['1'], + '_id': test_id, + 'projectId': test_id, + 'portfolioIds': [test_id], 'authorizations': [{ - 'projectId': '1', + 'projectId': test_id, 'authorizationLevel': 'EDIT' }] }) mocker.patch.object(DB, 'insert', return_value={ - '_id': '1', + '_id': test_id, 'name': 'test', 'targets': { 'enabledMetrics': ['test'], 'repeatsPerScenario': 2 }, - 'projectId': '1', + 'projectId': test_id, 'scenarioIds': [], }) mocker.patch.object(DB, 'update', return_value=None) res = client.post( - '/api/v2/projects/1/portfolios', + f'/api/v2/projects/{test_id}/portfolios', json={ 'portfolio': { 'name': 'test', diff --git a/api/opendc/api/v2/projects/projectId/test_endpoint.py b/api/opendc/api/v2/projects/projectId/test_endpoint.py index 7a862e8d..43fa5eed 100644 --- a/api/opendc/api/v2/projects/projectId/test_endpoint.py +++ b/api/opendc/api/v2/projects/projectId/test_endpoint.py @@ -1,14 +1,17 @@ from opendc.util.database import DB +test_id = 24 * '1' +test_id_2 = 24 * '2' + def test_get_project_non_existing(client, mocker): mocker.patch.object(DB, 'fetch_one', return_value=None) - assert '404' in client.get('/api/v2/projects/1').status + assert '404' in client.get(f'/api/v2/projects/{test_id}').status def test_get_project_no_authorizations(client, mocker): mocker.patch.object(DB, 'fetch_one', return_value={'authorizations': []}) - res = client.get('/api/v2/projects/1') + res = client.get(f'/api/v2/projects/{test_id}') assert '403' in res.status @@ -16,13 +19,13 @@ def test_get_project_not_authorized(client, mocker): mocker.patch.object(DB, 'fetch_one', return_value={ - '_id': '1', + '_id': test_id, 'authorizations': [{ - 'projectId': '2', + 'projectId': test_id_2, 'authorizationLevel': 'OWN' }] }) - res = client.get('/api/v2/projects/1') + res = client.get(f'/api/v2/projects/{test_id}') assert '403' in res.status @@ -30,84 +33,84 @@ def test_get_project(client, mocker): mocker.patch.object(DB, 'fetch_one', return_value={ - '_id': '1', + '_id': test_id, 'authorizations': [{ - 'projectId': '1', + 'projectId': test_id, 'authorizationLevel': 'EDIT' }] }) - res = client.get('/api/v2/projects/1') + res = client.get(f'/api/v2/projects/{test_id}') assert '200' in res.status def test_update_project_missing_parameter(client): - assert '400' in client.put('/api/v2/projects/1').status + assert '400' in client.put(f'/api/v2/projects/{test_id}').status def test_update_project_non_existing(client, mocker): mocker.patch.object(DB, 'fetch_one', return_value=None) - assert '404' in client.put('/api/v2/projects/1', json={'project': {'name': 'S'}}).status + assert '404' in client.put(f'/api/v2/projects/{test_id}', json={'project': {'name': 'S'}}).status def test_update_project_not_authorized(client, mocker): mocker.patch.object(DB, 'fetch_one', return_value={ - '_id': '1', + '_id': test_id, 'authorizations': [{ - 'projectId': '1', + 'projectId': test_id, 'authorizationLevel': 'VIEW' }] }) mocker.patch.object(DB, 'update', return_value={}) - assert '403' in client.put('/api/v2/projects/1', json={'project': {'name': 'S'}}).status + assert '403' in client.put(f'/api/v2/projects/{test_id}', json={'project': {'name': 'S'}}).status def test_update_project(client, mocker): mocker.patch.object(DB, 'fetch_one', return_value={ - '_id': '1', + '_id': test_id, 'authorizations': [{ - 'projectId': '1', + 'projectId': test_id, 'authorizationLevel': 'OWN' }] }) mocker.patch.object(DB, 'update', return_value={}) - res = client.put('/api/v2/projects/1', json={'project': {'name': 'S'}}) + res = client.put(f'/api/v2/projects/{test_id}', json={'project': {'name': 'S'}}) assert '200' in res.status def test_delete_project_non_existing(client, mocker): mocker.patch.object(DB, 'fetch_one', return_value=None) - assert '404' in client.delete('/api/v2/projects/1').status + assert '404' in client.delete(f'/api/v2/projects/{test_id}').status def test_delete_project_different_user(client, mocker): mocker.patch.object(DB, 'fetch_one', return_value={ - '_id': '1', + '_id': test_id, 'googleId': 'other_test', 'authorizations': [{ - 'projectId': '1', + 'projectId': test_id, 'authorizationLevel': 'VIEW' }], 'topologyIds': [] }) mocker.patch.object(DB, 'delete_one', return_value=None) - assert '403' in client.delete('/api/v2/projects/1').status + assert '403' in client.delete(f'/api/v2/projects/{test_id}').status def test_delete_project(client, mocker): mocker.patch.object(DB, 'fetch_one', return_value={ - '_id': '1', + '_id': test_id, 'googleId': 'test', 'authorizations': [{ - 'projectId': '1', + 'projectId': test_id, 'authorizationLevel': 'OWN' }], 'topologyIds': [], @@ -115,5 +118,5 @@ def test_delete_project(client, mocker): }) mocker.patch.object(DB, 'update', return_value=None) mocker.patch.object(DB, 'delete_one', return_value={'googleId': 'test'}) - res = client.delete('/api/v2/projects/1') + res = client.delete(f'/api/v2/projects/{test_id}') assert '200' in res.status diff --git a/api/opendc/api/v2/projects/projectId/topologies/endpoint.py b/api/opendc/api/v2/projects/projectId/topologies/endpoint.py index 211dc15d..44a0d575 100644 --- a/api/opendc/api/v2/projects/projectId/topologies/endpoint.py +++ b/api/opendc/api/v2/projects/projectId/topologies/endpoint.py @@ -17,7 +17,7 @@ def POST(request): project.check_user_access(request.google_id, True) topology = Topology({ - 'projectId': request.params_path['projectId'], + 'projectId': project.get_id(), 'name': request.params_body['topology']['name'], 'rooms': request.params_body['topology']['rooms'], }) diff --git a/api/opendc/api/v2/projects/projectId/topologies/test_endpoint.py b/api/opendc/api/v2/projects/projectId/topologies/test_endpoint.py index ca123a73..8ccebdad 100644 --- a/api/opendc/api/v2/projects/projectId/topologies/test_endpoint.py +++ b/api/opendc/api/v2/projects/projectId/topologies/test_endpoint.py @@ -1,17 +1,19 @@ from opendc.util.database import DB +test_id = 24 * '1' + def test_add_topology_missing_parameter(client): - assert '400' in client.post('/api/v2/projects/1/topologies').status + assert '400' in client.post(f'/api/v2/projects/{test_id}/topologies').status def test_add_topology(client, mocker): mocker.patch.object(DB, 'fetch_one', return_value={ - '_id': '1', + '_id': test_id, 'authorizations': [{ - 'projectId': '1', + 'projectId': test_id, 'authorizationLevel': 'OWN' }], 'topologyIds': [] @@ -19,13 +21,13 @@ def test_add_topology(client, mocker): mocker.patch.object(DB, 'insert', return_value={ - '_id': '1', + '_id': test_id, 'datetimeCreated': '000', 'datetimeLastEdited': '000', 'topologyIds': [] }) mocker.patch.object(DB, 'update', return_value={}) - res = client.post('/api/v2/projects/1/topologies', json={'topology': {'name': 'test project', 'rooms': []}}) + res = client.post(f'/api/v2/projects/{test_id}/topologies', json={'topology': {'name': 'test project', 'rooms': []}}) assert 'rooms' in res.json['content'] assert '200' in res.status @@ -34,14 +36,14 @@ def test_add_topology_not_authorized(client, mocker): mocker.patch.object(DB, 'fetch_one', return_value={ - '_id': '1', - 'projectId': '1', + '_id': test_id, + 'projectId': test_id, 'authorizations': [{ - 'projectId': '1', + 'projectId': test_id, 'authorizationLevel': 'VIEW' }] }) - assert '403' in client.post('/api/v2/projects/1/topologies', + assert '403' in client.post(f'/api/v2/projects/{test_id}/topologies', json={ 'topology': { 'name': 'test_topology', diff --git a/api/opendc/api/v2/projects/test_endpoint.py b/api/opendc/api/v2/projects/test_endpoint.py index a50735b0..cf02143c 100644 --- a/api/opendc/api/v2/projects/test_endpoint.py +++ b/api/opendc/api/v2/projects/test_endpoint.py @@ -1,16 +1,18 @@ from opendc.util.database import DB +test_id = 24 * '1' + def test_add_project_missing_parameter(client): assert '400' in client.post('/api/v2/projects').status def test_add_project(client, mocker): - mocker.patch.object(DB, 'fetch_one', return_value={'_id': '1', 'authorizations': []}) + mocker.patch.object(DB, 'fetch_one', return_value={'_id': test_id, 'authorizations': []}) mocker.patch.object(DB, 'insert', return_value={ - '_id': '1', + '_id': test_id, 'datetimeCreated': '000', 'datetimeLastEdited': '000', 'topologyIds': [] diff --git a/api/opendc/api/v2/scenarios/scenarioId/endpoint.py b/api/opendc/api/v2/scenarios/scenarioId/endpoint.py index 02d39063..88a74e9c 100644 --- a/api/opendc/api/v2/scenarios/scenarioId/endpoint.py +++ b/api/opendc/api/v2/scenarios/scenarioId/endpoint.py @@ -46,10 +46,12 @@ def DELETE(request): scenario.check_exists() scenario.check_user_access(request.google_id, True) + scenario_id = scenario.get_id() + portfolio = Portfolio.from_id(scenario.obj['portfolioId']) portfolio.check_exists() - if request.params_path['scenarioId'] in portfolio.obj['scenarioIds']: - portfolio.obj['scenarioIds'].remove(request.params_path['scenarioId']) + if scenario_id in portfolio.obj['scenarioIds']: + portfolio.obj['scenarioIds'].remove(scenario_id) portfolio.update() old_object = scenario.delete() diff --git a/api/opendc/api/v2/scenarios/scenarioId/test_endpoint.py b/api/opendc/api/v2/scenarios/scenarioId/test_endpoint.py index c3be0215..386a9eea 100644 --- a/api/opendc/api/v2/scenarios/scenarioId/test_endpoint.py +++ b/api/opendc/api/v2/scenarios/scenarioId/test_endpoint.py @@ -1,9 +1,12 @@ from opendc.util.database import DB +test_id = 24 * '1' +test_id_2 = 24 * '2' + def test_get_scenario_non_existing(client, mocker): mocker.patch.object(DB, 'fetch_one', return_value=None) - assert '404' in client.get('/api/v2/scenarios/1').status + assert '404' in client.get(f'/api/v2/scenarios/{test_id}').status def test_get_scenario_no_authorizations(client, mocker): @@ -11,7 +14,7 @@ def test_get_scenario_no_authorizations(client, mocker): 'portfolioId': '1', 'authorizations': [] }) - res = client.get('/api/v2/scenarios/1') + res = client.get(f'/api/v2/scenarios/{test_id}') assert '403' in res.status @@ -19,15 +22,15 @@ def test_get_scenario_not_authorized(client, mocker): mocker.patch.object(DB, 'fetch_one', return_value={ - 'projectId': '1', - 'portfolioId': '1', - '_id': '1', + 'projectId': test_id, + 'portfolioId': test_id, + '_id': test_id, 'authorizations': [{ - 'projectId': '2', + 'projectId': test_id_2, 'authorizationLevel': 'OWN' }] }) - res = client.get('/api/v2/scenarios/1') + res = client.get(f'/api/v2/scenarios/{test_id}') assert '403' in res.status @@ -35,25 +38,25 @@ def test_get_scenario(client, mocker): mocker.patch.object(DB, 'fetch_one', return_value={ - 'projectId': '1', - 'portfolioId': '1', - '_id': '1', + 'projectId': test_id, + 'portfolioId': test_id, + '_id': test_id, 'authorizations': [{ - 'projectId': '1', + 'projectId': test_id, 'authorizationLevel': 'EDIT' }] }) - res = client.get('/api/v2/scenarios/1') + res = client.get(f'/api/v2/scenarios/{test_id}') assert '200' in res.status def test_update_scenario_missing_parameter(client): - assert '400' in client.put('/api/v2/scenarios/1').status + assert '400' in client.put(f'/api/v2/scenarios/{test_id}').status def test_update_scenario_non_existing(client, mocker): mocker.patch.object(DB, 'fetch_one', return_value=None) - assert '404' in client.put('/api/v2/scenarios/1', json={ + assert '404' in client.put(f'/api/v2/scenarios/{test_id}', json={ 'scenario': { 'name': 'test', } @@ -64,16 +67,16 @@ def test_update_scenario_not_authorized(client, mocker): mocker.patch.object(DB, 'fetch_one', return_value={ - '_id': '1', - 'projectId': '1', - 'portfolioId': '1', + '_id': test_id, + 'projectId': test_id, + 'portfolioId': test_id, 'authorizations': [{ - 'projectId': '1', + 'projectId': test_id, 'authorizationLevel': 'VIEW' }] }) mocker.patch.object(DB, 'update', return_value={}) - assert '403' in client.put('/api/v2/scenarios/1', json={ + assert '403' in client.put(f'/api/v2/scenarios/{test_id}', json={ 'scenario': { 'name': 'test', } @@ -84,11 +87,11 @@ def test_update_scenario(client, mocker): mocker.patch.object(DB, 'fetch_one', return_value={ - '_id': '1', - 'projectId': '1', - 'portfolioId': '1', + '_id': test_id, + 'projectId': test_id, + 'portfolioId': test_id, 'authorizations': [{ - 'projectId': '1', + 'projectId': test_id, 'authorizationLevel': 'OWN' }], 'targets': { @@ -98,7 +101,7 @@ def test_update_scenario(client, mocker): }) mocker.patch.object(DB, 'update', return_value={}) - res = client.put('/api/v2/scenarios/1', json={'scenario': { + res = client.put(f'/api/v2/scenarios/{test_id}', json={'scenario': { 'name': 'test', }}) assert '200' in res.status @@ -106,41 +109,41 @@ def test_update_scenario(client, mocker): def test_delete_project_non_existing(client, mocker): mocker.patch.object(DB, 'fetch_one', return_value=None) - assert '404' in client.delete('/api/v2/scenarios/1').status + assert '404' in client.delete(f'/api/v2/scenarios/{test_id}').status def test_delete_project_different_user(client, mocker): mocker.patch.object(DB, 'fetch_one', return_value={ - '_id': '1', - 'projectId': '1', - 'portfolioId': '1', + '_id': test_id, + 'projectId': test_id, + 'portfolioId': test_id, 'googleId': 'other_test', 'authorizations': [{ - 'projectId': '1', + 'projectId': test_id, 'authorizationLevel': 'VIEW' }] }) mocker.patch.object(DB, 'delete_one', return_value=None) - assert '403' in client.delete('/api/v2/scenarios/1').status + assert '403' in client.delete(f'/api/v2/scenarios/{test_id}').status def test_delete_project(client, mocker): mocker.patch.object(DB, 'fetch_one', return_value={ - '_id': '1', - 'projectId': '1', - 'portfolioId': '1', + '_id': test_id, + 'projectId': test_id, + 'portfolioId': test_id, 'googleId': 'test', - 'scenarioIds': ['1'], + 'scenarioIds': [test_id], 'authorizations': [{ - 'projectId': '1', + 'projectId': test_id, 'authorizationLevel': 'OWN' }] }) mocker.patch.object(DB, 'delete_one', return_value={}) mocker.patch.object(DB, 'update', return_value=None) - res = client.delete('/api/v2/scenarios/1') + res = client.delete(f'/api/v2/scenarios/{test_id}') assert '200' in res.status diff --git a/api/opendc/api/v2/topologies/topologyId/endpoint.py b/api/opendc/api/v2/topologies/topologyId/endpoint.py index 512b050a..ea82b2e2 100644 --- a/api/opendc/api/v2/topologies/topologyId/endpoint.py +++ b/api/opendc/api/v2/topologies/topologyId/endpoint.py @@ -45,10 +45,12 @@ def DELETE(request): topology.check_exists() topology.check_user_access(request.google_id, True) + topology_id = topology.get_id() + project = Project.from_id(topology.obj['projectId']) project.check_exists() - if request.params_path['topologyId'] in project.obj['topologyIds']: - project.obj['topologyIds'].remove(request.params_path['topologyId']) + if topology_id in project.obj['topologyIds']: + project.obj['topologyIds'].remove(topology_id) project.update() old_object = topology.delete() diff --git a/api/opendc/api/v2/topologies/topologyId/test_endpoint.py b/api/opendc/api/v2/topologies/topologyId/test_endpoint.py index b25cb798..76243ad6 100644 --- a/api/opendc/api/v2/topologies/topologyId/test_endpoint.py +++ b/api/opendc/api/v2/topologies/topologyId/test_endpoint.py @@ -1,18 +1,21 @@ from opendc.util.database import DB +test_id = 24 * '1' +test_id_2 = 24 * '2' + def test_get_topology(client, mocker): mocker.patch.object(DB, 'fetch_one', return_value={ - '_id': '1', - 'projectId': '1', + '_id': test_id, + 'projectId': test_id, 'authorizations': [{ - 'projectId': '1', + 'projectId': test_id, 'authorizationLevel': 'EDIT' }] }) - res = client.get('/api/v2/topologies/1') + res = client.get(f'/api/v2/topologies/{test_id}') assert '200' in res.status @@ -25,45 +28,45 @@ def test_get_topology_not_authorized(client, mocker): mocker.patch.object(DB, 'fetch_one', return_value={ - '_id': '1', - 'projectId': '1', + '_id': test_id, + 'projectId': test_id, 'authorizations': [{ - 'projectId': '2', + 'projectId': test_id_2, 'authorizationLevel': 'OWN' }] }) - res = client.get('/api/v2/topologies/1') + res = client.get(f'/api/v2/topologies/{test_id}') assert '403' in res.status def test_get_topology_no_authorizations(client, mocker): - mocker.patch.object(DB, 'fetch_one', return_value={'projectId': '1', 'authorizations': []}) - res = client.get('/api/v2/topologies/1') + mocker.patch.object(DB, 'fetch_one', return_value={'projectId': test_id, 'authorizations': []}) + res = client.get(f'/api/v2/topologies/{test_id}') assert '403' in res.status def test_update_topology_missing_parameter(client): - assert '400' in client.put('/api/v2/topologies/1').status + assert '400' in client.put(f'/api/v2/topologies/{test_id}').status def test_update_topology_non_existent(client, mocker): mocker.patch.object(DB, 'fetch_one', return_value=None) - assert '404' in client.put('/api/v2/topologies/1', json={'topology': {'name': 'test_topology', 'rooms': {}}}).status + assert '404' in client.put(f'/api/v2/topologies/{test_id}', json={'topology': {'name': 'test_topology', 'rooms': {}}}).status def test_update_topology_not_authorized(client, mocker): mocker.patch.object(DB, 'fetch_one', return_value={ - '_id': '1', - 'projectId': '1', + '_id': test_id, + 'projectId': test_id, 'authorizations': [{ - 'projectId': '1', + 'projectId': test_id, 'authorizationLevel': 'VIEW' }] }) mocker.patch.object(DB, 'update', return_value={}) - assert '403' in client.put('/api/v2/topologies/1', json={ + assert '403' in client.put(f'/api/v2/topologies/{test_id}', json={ 'topology': { 'name': 'updated_topology', 'rooms': {} @@ -75,16 +78,16 @@ def test_update_topology(client, mocker): mocker.patch.object(DB, 'fetch_one', return_value={ - '_id': '1', - 'projectId': '1', + '_id': test_id, + 'projectId': test_id, 'authorizations': [{ - 'projectId': '1', + 'projectId': test_id, 'authorizationLevel': 'OWN' }] }) mocker.patch.object(DB, 'update', return_value={}) - assert '200' in client.put('/api/v2/topologies/1', json={ + assert '200' in client.put(f'/api/v2/topologies/{test_id}', json={ 'topology': { 'name': 'updated_topology', 'rooms': {} @@ -96,21 +99,21 @@ def test_delete_topology(client, mocker): mocker.patch.object(DB, 'fetch_one', return_value={ - '_id': '1', - 'projectId': '1', + '_id': test_id, + 'projectId': test_id, 'googleId': 'test', - 'topologyIds': ['1'], + 'topologyIds': [test_id], 'authorizations': [{ - 'projectId': '1', + 'projectId': test_id, 'authorizationLevel': 'OWN' }] }) mocker.patch.object(DB, 'delete_one', return_value={}) mocker.patch.object(DB, 'update', return_value=None) - res = client.delete('/api/v2/topologies/1') + res = client.delete(f'/api/v2/topologies/{test_id}') assert '200' in res.status def test_delete_nonexistent_topology(client, mocker): mocker.patch.object(DB, 'fetch_one', return_value=None) - assert '404' in client.delete('/api/v2/topologies/1').status + assert '404' in client.delete(f'/api/v2/topologies/{test_id}').status diff --git a/api/opendc/api/v2/traces/traceId/test_endpoint.py b/api/opendc/api/v2/traces/traceId/test_endpoint.py index 56792ca9..144f02bb 100644 --- a/api/opendc/api/v2/traces/traceId/test_endpoint.py +++ b/api/opendc/api/v2/traces/traceId/test_endpoint.py @@ -1,13 +1,15 @@ from opendc.util.database import DB +test_id = 24 * '1' + def test_get_trace_non_existing(client, mocker): mocker.patch.object(DB, 'fetch_one', return_value=None) - assert '404' in client.get('/api/v2/traces/1').status + assert '404' in client.get(f'/api/v2/traces/{test_id}').status def test_get_trace(client, mocker): mocker.patch.object(DB, 'fetch_one', return_value={'name': 'test trace'}) - res = client.get('/api/v2/traces/1') + res = client.get(f'/api/v2/traces/{test_id}') assert 'name' in res.json['content'] assert '200' in res.status diff --git a/api/opendc/api/v2/users/userId/test_endpoint.py b/api/opendc/api/v2/users/userId/test_endpoint.py index cdff2229..89549f33 100644 --- a/api/opendc/api/v2/users/userId/test_endpoint.py +++ b/api/opendc/api/v2/users/userId/test_endpoint.py @@ -1,53 +1,56 @@ from opendc.util.database import DB +test_id = 24 * '1' + def test_get_user_non_existing(client, mocker): mocker.patch.object(DB, 'fetch_one', return_value=None) - assert '404' in client.get('/api/v2/users/1').status + assert '404' in client.get(f'/api/v2/users/{test_id}').status def test_get_user(client, mocker): mocker.patch.object(DB, 'fetch_one', return_value={'email': 'test@test.com'}) - res = client.get('/api/v2/users/1') + res = client.get(f'/api/v2/users/{test_id}') assert 'email' in res.json['content'] assert '200' in res.status def test_update_user_missing_parameter(client): - assert '400' in client.put('/api/v2/users/1').status + assert '400' in client.put(f'/api/v2/users/{test_id}').status def test_update_user_non_existing(client, mocker): mocker.patch.object(DB, 'fetch_one', return_value=None) - assert '404' in client.put('/api/v2/users/1', json={'user': {'givenName': 'A', 'familyName': 'B'}}).status + assert '404' in client.put(f'/api/v2/users/{test_id}', json={'user': {'givenName': 'A', 'familyName': 'B'}}).status def test_update_user_different_user(client, mocker): - mocker.patch.object(DB, 'fetch_one', return_value={'_id': '1', 'googleId': 'other_test'}) - assert '403' in client.put('/api/v2/users/1', json={'user': {'givenName': 'A', 'familyName': 'B'}}).status + mocker.patch.object(DB, 'fetch_one', return_value={'_id': test_id, 'googleId': 'other_test'}) + assert '403' in client.put(f'/api/v2/users/{test_id}', json={'user': {'givenName': 'A', 'familyName': 'B'}}).status def test_update_user(client, mocker): - mocker.patch.object(DB, 'fetch_one', return_value={'_id': '1', 'googleId': 'test'}) + mocker.patch.object(DB, 'fetch_one', return_value={'_id': test_id, 'googleId': 'test'}) mocker.patch.object(DB, 'update', return_value={'givenName': 'A', 'familyName': 'B'}) - res = client.put('/api/v2/users/1', json={'user': {'givenName': 'A', 'familyName': 'B'}}) + res = client.put(f'/api/v2/users/{test_id}', json={'user': {'givenName': 'A', 'familyName': 'B'}}) assert 'givenName' in res.json['content'] assert '200' in res.status def test_delete_user_non_existing(client, mocker): mocker.patch.object(DB, 'fetch_one', return_value=None) - assert '404' in client.delete('/api/v2/users/1').status + assert '404' in client.delete(f'/api/v2/users/{test_id}').status def test_delete_user_different_user(client, mocker): - mocker.patch.object(DB, 'fetch_one', return_value={'_id': '1', 'googleId': 'other_test'}) - assert '403' in client.delete('/api/v2/users/1').status + mocker.patch.object(DB, 'fetch_one', return_value={'_id': test_id, 'googleId': 'other_test'}) + assert '403' in client.delete(f'/api/v2/users/{test_id}').status def test_delete_user(client, mocker): - mocker.patch.object(DB, 'fetch_one', return_value={'_id': '1', 'googleId': 'test', 'authorizations': []}) + mocker.patch.object(DB, 'fetch_one', return_value={'_id': test_id, 'googleId': 'test', 'authorizations': []}) mocker.patch.object(DB, 'delete_one', return_value={'googleId': 'test'}) - res = client.delete('/api/v2/users/1') + res = client.delete(f'/api/v2/users/{test_id}', ) + assert 'googleId' in res.json['content'] assert '200' in res.status diff --git a/api/opendc/models/model.py b/api/opendc/models/model.py index bcb833ae..f9dfc9ad 100644 --- a/api/opendc/models/model.py +++ b/api/opendc/models/model.py @@ -1,4 +1,4 @@ -from uuid import uuid4 +from bson.objectid import ObjectId from opendc.util.database import DB from opendc.util.exceptions import ClientError @@ -13,6 +13,11 @@ class Model: @classmethod def from_id(cls, _id): """Fetches the document with given ID from the collection.""" + if isinstance(_id, str) and len(_id) == 24: + _id = ObjectId(_id) + elif not isinstance(_id, ObjectId): + return cls(None) + return cls(DB.fetch_one({'_id': _id}, cls.collection_name)) @classmethod @@ -25,7 +30,7 @@ class Model: def get_id(self): """Returns the ID of the enclosed object.""" - return str(self.obj['_id']) + return self.obj['_id'] def check_exists(self): """Raises an error if the enclosed object does not exist.""" @@ -42,7 +47,7 @@ class Model: def insert(self): """Inserts the enclosed object and generates a UUID for it.""" - self.obj['_id'] = str(uuid4()) + self.obj['_id'] = ObjectId() DB.insert(self.obj, self.collection_name) def update(self): diff --git a/api/opendc/util/database.py b/api/opendc/util/database.py index 80cdcbab..dd26533d 100644 --- a/api/opendc/util/database.py +++ b/api/opendc/util/database.py @@ -1,8 +1,6 @@ -import json import urllib.parse from datetime import datetime -from bson.json_util import dumps from pymongo import MongoClient DATETIME_STRING_FORMAT = '%Y-%m-%dT%H:%M:%S' @@ -31,32 +29,25 @@ class Database: The query needs to be in json format, i.e.: `{'name': prefab_name}`. """ - bson = getattr(self.opendc_db, collection).find_one(query) - - return self.convert_bson_to_json(bson) + return getattr(self.opendc_db, collection).find_one(query) def fetch_all(self, query, collection): """Uses existing mongo connection to return all documents matching a given query, as a list of JSON objects. The query needs to be in json format, i.e.: `{'name': prefab_name}`. """ - results = [] cursor = getattr(self.opendc_db, collection).find(query) - for doc in cursor: - results.append(self.convert_bson_to_json(doc)) - return results + return list(cursor) def insert(self, obj, collection): """Updates an existing object.""" bson = getattr(self.opendc_db, collection).insert(obj) - return self.convert_bson_to_json(bson) + return bson def update(self, _id, obj, collection): """Updates an existing object.""" - bson = getattr(self.opendc_db, collection).update({'_id': _id}, obj) - - return self.convert_bson_to_json(bson) + return getattr(self.opendc_db, collection).update({'_id': _id}, obj) def delete_one(self, query, collection): """Deletes one object matching the given query. @@ -73,12 +64,6 @@ class Database: getattr(self.opendc_db, collection).delete_many(query) @staticmethod - def convert_bson_to_json(bson): - """Converts a BSON representation to JSON and returns the JSON representation.""" - json_string = dumps(bson) - return json.loads(json_string) - - @staticmethod def datetime_to_string(datetime_to_convert): """Return a database-compatible string representation of the given datetime object.""" return datetime_to_convert.strftime(DATETIME_STRING_FORMAT) diff --git a/api/opendc/util/json.py b/api/opendc/util/json.py new file mode 100644 index 00000000..2ef4f965 --- /dev/null +++ b/api/opendc/util/json.py @@ -0,0 +1,12 @@ +import flask +from bson.objectid import ObjectId + + +class JSONEncoder(flask.json.JSONEncoder): + """ + A customized JSON encoder to handle unsupported types. + """ + def default(self, o): + if isinstance(o, ObjectId): + return str(o) + return flask.json.JSONEncoder.default(self, o) diff --git a/api/opendc/util/path_parser.py b/api/opendc/util/path_parser.py index a8bbdeba..c8452f20 100644 --- a/api/opendc/util/path_parser.py +++ b/api/opendc/util/path_parser.py @@ -31,9 +31,6 @@ def parse(version, endpoint_path): for (name, value) in zip(path, endpoint_path_parts): if name.startswith('{'): - try: - parameters[name.strip('{}')] = int(value) - except: - parameters[name.strip('{}')] = value + parameters[name.strip('{}')] = value return '{}/{}'.format(version, '/'.join(path)), parameters diff --git a/api/opendc/util/rest.py b/api/opendc/util/rest.py index abd2f3de..c9e98295 100644 --- a/api/opendc/util/rest.py +++ b/api/opendc/util/rest.py @@ -138,4 +138,4 @@ class Response: if self.content is not None: data['content'] = self.content - return json.dumps(data) + return json.dumps(data, default=str) |
