summaryrefslogtreecommitdiff
path: root/opendc-web/opendc-web-api/opendc/api/v2/scenarios/scenarioId
diff options
context:
space:
mode:
authorFabian Mastenbroek <mail.fabianm@gmail.com>2021-04-25 21:53:42 +0200
committerGitHub <noreply@github.com>2021-04-25 21:53:42 +0200
commit128f76f7fd7c8abb41a3bbbd9f1980cbc20ae7a5 (patch)
treeadd513890005233a7784466797bfe6f5052e9eeb /opendc-web/opendc-web-api/opendc/api/v2/scenarios/scenarioId
parent128a1db017545597a5c035b7960eb3fd36b5f987 (diff)
parent57b54b59ed74ec37338ae26b3864d051255aba49 (diff)
build: Flatten project structure
This change updates the project structure to become flattened. Previously, the simulator, frontend and API each lived into their own directory. With this change, all modules of the project live in the top-level directory of the repository.
Diffstat (limited to 'opendc-web/opendc-web-api/opendc/api/v2/scenarios/scenarioId')
-rw-r--r--opendc-web/opendc-web-api/opendc/api/v2/scenarios/scenarioId/__init__.py0
-rw-r--r--opendc-web/opendc-web-api/opendc/api/v2/scenarios/scenarioId/endpoint.py59
-rw-r--r--opendc-web/opendc-web-api/opendc/api/v2/scenarios/scenarioId/test_endpoint.py149
3 files changed, 208 insertions, 0 deletions
diff --git a/opendc-web/opendc-web-api/opendc/api/v2/scenarios/scenarioId/__init__.py b/opendc-web/opendc-web-api/opendc/api/v2/scenarios/scenarioId/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/opendc-web/opendc-web-api/opendc/api/v2/scenarios/scenarioId/__init__.py
diff --git a/opendc-web/opendc-web-api/opendc/api/v2/scenarios/scenarioId/endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/scenarios/scenarioId/endpoint.py
new file mode 100644
index 00000000..88a74e9c
--- /dev/null
+++ b/opendc-web/opendc-web-api/opendc/api/v2/scenarios/scenarioId/endpoint.py
@@ -0,0 +1,59 @@
+from opendc.models.scenario import Scenario
+from opendc.models.portfolio import Portfolio
+from opendc.util.rest import Response
+
+
+def GET(request):
+ """Get this Scenario."""
+
+ request.check_required_parameters(path={'scenarioId': 'string'})
+
+ scenario = Scenario.from_id(request.params_path['scenarioId'])
+
+ scenario.check_exists()
+ scenario.check_user_access(request.google_id, False)
+
+ return Response(200, 'Successfully retrieved scenario.', scenario.obj)
+
+
+def PUT(request):
+ """Update this Scenarios name."""
+
+ request.check_required_parameters(path={'scenarioId': 'string'}, body={'scenario': {
+ 'name': 'string',
+ }})
+
+ scenario = Scenario.from_id(request.params_path['scenarioId'])
+
+ scenario.check_exists()
+ scenario.check_user_access(request.google_id, True)
+
+ scenario.set_property('name',
+ request.params_body['scenario']['name'])
+
+ scenario.update()
+
+ return Response(200, 'Successfully updated scenario.', scenario.obj)
+
+
+def DELETE(request):
+ """Delete this Scenario."""
+
+ request.check_required_parameters(path={'scenarioId': 'string'})
+
+ scenario = Scenario.from_id(request.params_path['scenarioId'])
+
+ 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 scenario_id in portfolio.obj['scenarioIds']:
+ portfolio.obj['scenarioIds'].remove(scenario_id)
+ portfolio.update()
+
+ old_object = scenario.delete()
+
+ return Response(200, 'Successfully deleted scenario.', old_object)
diff --git a/opendc-web/opendc-web-api/opendc/api/v2/scenarios/scenarioId/test_endpoint.py b/opendc-web/opendc-web-api/opendc/api/v2/scenarios/scenarioId/test_endpoint.py
new file mode 100644
index 00000000..cd4bcdf8
--- /dev/null
+++ b/opendc-web/opendc-web-api/opendc/api/v2/scenarios/scenarioId/test_endpoint.py
@@ -0,0 +1,149 @@
+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(f'/v2/scenarios/{test_id}').status
+
+
+def test_get_scenario_no_authorizations(client, mocker):
+ mocker.patch.object(DB, 'fetch_one', return_value={
+ 'portfolioId': '1',
+ 'authorizations': []
+ })
+ res = client.get(f'/v2/scenarios/{test_id}')
+ assert '403' in res.status
+
+
+def test_get_scenario_not_authorized(client, mocker):
+ mocker.patch.object(DB,
+ 'fetch_one',
+ return_value={
+ 'projectId': test_id,
+ 'portfolioId': test_id,
+ '_id': test_id,
+ 'authorizations': [{
+ 'projectId': test_id_2,
+ 'authorizationLevel': 'OWN'
+ }]
+ })
+ res = client.get(f'/v2/scenarios/{test_id}')
+ assert '403' in res.status
+
+
+def test_get_scenario(client, mocker):
+ mocker.patch.object(DB,
+ 'fetch_one',
+ return_value={
+ 'projectId': test_id,
+ 'portfolioId': test_id,
+ '_id': test_id,
+ 'authorizations': [{
+ 'projectId': test_id,
+ 'authorizationLevel': 'EDIT'
+ }]
+ })
+ res = client.get(f'/v2/scenarios/{test_id}')
+ assert '200' in res.status
+
+
+def test_update_scenario_missing_parameter(client):
+ assert '400' in client.put(f'/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(f'/v2/scenarios/{test_id}', json={
+ 'scenario': {
+ 'name': 'test',
+ }
+ }).status
+
+
+def test_update_scenario_not_authorized(client, mocker):
+ mocker.patch.object(DB,
+ 'fetch_one',
+ return_value={
+ '_id': test_id,
+ 'projectId': test_id,
+ 'portfolioId': test_id,
+ 'authorizations': [{
+ 'projectId': test_id,
+ 'authorizationLevel': 'VIEW'
+ }]
+ })
+ mocker.patch.object(DB, 'update', return_value={})
+ assert '403' in client.put(f'/v2/scenarios/{test_id}', json={
+ 'scenario': {
+ 'name': 'test',
+ }
+ }).status
+
+
+def test_update_scenario(client, mocker):
+ mocker.patch.object(DB,
+ 'fetch_one',
+ return_value={
+ '_id': test_id,
+ 'projectId': test_id,
+ 'portfolioId': test_id,
+ 'authorizations': [{
+ 'projectId': test_id,
+ 'authorizationLevel': 'OWN'
+ }],
+ 'targets': {
+ 'enabledMetrics': [],
+ 'repeatsPerScenario': 1
+ }
+ })
+ mocker.patch.object(DB, 'update', return_value={})
+
+ res = client.put(f'/v2/scenarios/{test_id}', json={'scenario': {
+ 'name': 'test',
+ }})
+ 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(f'/v2/scenarios/{test_id}').status
+
+
+def test_delete_project_different_user(client, mocker):
+ mocker.patch.object(DB,
+ 'fetch_one',
+ return_value={
+ '_id': test_id,
+ 'projectId': test_id,
+ 'portfolioId': test_id,
+ 'googleId': 'other_test',
+ 'authorizations': [{
+ 'projectId': test_id,
+ 'authorizationLevel': 'VIEW'
+ }]
+ })
+ mocker.patch.object(DB, 'delete_one', return_value=None)
+ assert '403' in client.delete(f'/v2/scenarios/{test_id}').status
+
+
+def test_delete_project(client, mocker):
+ mocker.patch.object(DB,
+ 'fetch_one',
+ return_value={
+ '_id': test_id,
+ 'projectId': test_id,
+ 'portfolioId': test_id,
+ 'googleId': 'test',
+ 'scenarioIds': [test_id],
+ 'authorizations': [{
+ 'projectId': test_id,
+ 'authorizationLevel': 'OWN'
+ }]
+ })
+ mocker.patch.object(DB, 'delete_one', return_value={})
+ mocker.patch.object(DB, 'update', return_value=None)
+ res = client.delete(f'/v2/scenarios/{test_id}')
+ assert '200' in res.status