async def test_read(client, logged_user, tokens_db, fake_tokens): # list all url = client.app.router["list_tokens"].url_for() assert "/v0/me/tokens" == str(url) resp = await client.get(url) payload = await resp.json() assert resp.status == 200, payload data, error = unwrap_envelope(payload) assert not error assert data == fake_tokens # get one expected = random.choice(fake_tokens) sid = expected['service'] url = client.app.router["get_token"].url_for(service=sid) assert "/v0/me/tokens/%s" % sid == str(url) resp = await client.get(url) payload = await resp.json() assert resp.status == 200, payload data, error = unwrap_envelope(payload) assert not error assert data == expected
async def test_update(client, fake_db, fake_project, mocker): pid = fake_project["uuid"] #----------------- # # In a PUT request, the enclosed entity is considered to be a modified version of # the resource stored on the origin server, and the client is requesting that the # stored version be replaced. # # With PATCH, however, the enclosed entity contains a set of instructions describing how a # resource currently residing on the origin server should be modified to produce a new version. # # Also, another difference is that when you want to update a resource with PUT request, you have to send # the full payload as the request whereas with PATCH, you only send the parameters which you want to update. # mock = mocker.patch( 'simcore_service_webserver.projects.projects_handlers.ProjectDB.update_user_project', return_value=Future()) mock.return_value.set_result(None) url = client.app.router["replace_project"].url_for(project_id=pid) assert str(url) == PREFIX + "/%s/%s" % (RESOURCE_NAME, pid) # PUT /v0/projects/{project_id} resp = await client.put(url, json=fake_project) payload = await resp.json() assert resp.status == 200, payload project, error = unwrap_envelope(payload) assert not error assert not project mock.assert_called_once_with(fake_project, ANONYMOUS_UID, pid, db_engine=None)
async def assert_status(response: web.Response, expected_cls: web.HTTPException, expected_msg: str = None): """ Asserts for enveloped responses """ data, error = unwrap_envelope(await response.json()) assert response.status == expected_cls.status_code, (data, error) if issubclass(expected_cls, web.HTTPError): do_assert_error(data, error, expected_cls, expected_msg) elif issubclass(expected_cls, web.HTTPNoContent): assert not data, pformat(data) assert not error, pformat(error) else: # with a 200, data may still be empty see # https://medium.com/@santhoshkumarkrishna/http-get-rest-api-no-content-404-vs-204-vs-200-6dd869e3af1d # assert data is not None, pformat(data) assert not error, pformat(error) if expected_msg: assert expected_msg in data["message"] return data, error
async def test_update(client, logged_user, tokens_db, fake_tokens): selected = random.choice(fake_tokens) sid = selected['service'] url = client.app.router["get_token"].url_for(service=sid) assert "/v0/me/tokens/%s" % sid == str(url) resp = await client.put( url, json={'token_secret': 'some completely new secret'}) payload = await resp.json() assert resp.status == 200, payload data, error = unwrap_envelope(payload) assert not error assert not data # check in db token_in_db = await get_token_from_db(tokens_db, token_service=sid) assert token_in_db['token_data'][ 'token_secret'] == 'some completely new secret' assert token_in_db['token_data']['token_secret'] != selected['token_secret'] selected['token_secret'] = 'some completely new secret' assert token_in_db['token_data'] == selected
async def test_registration_with_confirmation(client, capsys, monkeypatch): monkeypatch.setitem(cfg, "REGISTRATION_CONFIRMATION_REQUIRED", True) db = get_storage(client.app) url = client.app.router["auth_register"].url_for() r = await client.post(url, json={ "email": EMAIL, "password": PASSWORD, "confirm": PASSWORD }) data, error = unwrap_envelope(await r.json()) assert r.status == 200, (data, error) user = await db.get_user({"email": EMAIL}) assert user["status"] == UserStatus.CONFIRMATION_PENDING.name assert "verification link" in data["message"] # retrieves sent link by email (see monkeypatch of email in conftest.py) out, err = capsys.readouterr() link = parse_link(out) assert "/auth/confirmation/" in str(link) resp = await client.get(link) text = await resp.text() assert "welcome to fake web front-end" in text assert resp.status == 200 user = await db.get_user({"email": EMAIL}) assert user["status"] == UserStatus.ACTIVE.name await db.delete_user(user)
async def copy_data_folders_from_project(app, source_project, destination_project, nodes_map, user_id): # TODO: optimize if project has actualy data or not before doing the call client, api_endpoint = _get_storage_client(app) # /simcore-s3/folders: url = (api_endpoint / "simcore-s3/folders").with_query(user_id=user_id) async with client.post( url, json={ "source": source_project, "destination": destination_project, "nodes_map": nodes_map, }, ssl=False, ) as resp: payload = await resp.json() updated_project, error = unwrap_envelope(payload) if error: msg = "Cannot copy project data in storage: %s" % pformat(error) log.error(msg) # TODO: should reconstruct error and rethrow same exception as storage service? raise web.HTTPServiceUnavailable(reason=msg) return updated_project
async def _create_project(client, project): url = client.app.router["create_projects"].url_for() resp = await client.post(url, json=project) payload = await resp.json() assert resp.status == 201, payload project, error = unwrap_envelope(payload) assert project assert not error, pprint(error)
async def _delete_project(client, pid): url = client.app.router["delete_project"].url_for(project_id=pid) resp = await client.delete(url) payload = await resp.json() assert resp.status == 204, payload project, error = unwrap_envelope(payload) assert not error, pprint(error) assert not project
async def test_envelope_middleware(path, expected_data, client, specs): base = openapi.get_base_path(specs) response = await client.get(base + path) payload = await response.json() assert is_enveloped(payload) data, error = unwrap_envelope(payload) assert not error assert data == expected_data
async def test_validate_handlers(path, client, specs): base = openapi.get_base_path(specs) response = await client.get(base + path) payload = await response.json() assert is_enveloped(payload) data, error = unwrap_envelope(payload) assert not error assert data
async def _get_user_projects(client): url = client.app.router["list_projects"].url_for() resp = await client.get(url.with_query(start=0, count=3, type="user")) payload = await resp.json() assert resp.status == 200, payload projects, error = unwrap_envelope(payload) assert not error, pprint(error) return projects
async def _update_project(client, project, pid): # PUT /v0/projects/{project_id} url = client.app.router["replace_project"].url_for(project_id=pid) resp = await client.put(url, json=project) payload = await resp.json() assert resp.status == 200, payload project, error = unwrap_envelope(payload) assert not error, pprint(error) assert not project
async def test_delete_invalid_project(loop, client): async with LoggedUser(client): url = client.app.router["delete_project"].url_for( project_id="some-fake-id") resp = await client.delete(url) payload = await resp.json() assert resp.status == 404, pprint(payload) data, error = unwrap_envelope(payload) assert not data assert error
async def _list_projects(client) -> List[Dict]: # GET /v0/projects url = client.app.router["list_projects"].url_for() resp = await client.get(url.with_query(start=0, count=3)) payload = await resp.json() assert resp.status == 200, payload projects, error = unwrap_envelope(payload) assert not error, pprint(error) return projects
async def _get_project(client, pid) -> Dict: url = client.app.router["get_project"].url_for(project_id=pid) resp = await client.get(url) payload = await resp.json() assert resp.status == 200, payload project, error = unwrap_envelope(payload) assert not error, pprint(error) assert project return project
async def test_list(client, mocker, fake_project): #----------------- mock = mocker.patch( 'simcore_service_webserver.projects.projects_handlers.ProjectDB.load_user_projects', return_value=Future()) mock.return_value.set_result([fake_project]) # list all user projects url = client.app.router["list_projects"].url_for() assert str(url) == PREFIX + "/%s" % RESOURCE_NAME # GET /v0/projects resp = await client.get(url.with_query(start=1, count=2)) payload = await resp.json() assert resp.status == 200, payload projects, error = unwrap_envelope(payload) assert not error assert not projects mock.assert_called_once_with(user_id=ANONYMOUS_UID, db_engine=None) resp = await client.get(url.with_query(start=0, count=0)) payload = await resp.json() assert resp.status == 200, payload projects, error = unwrap_envelope(payload) assert not error assert not projects mock.assert_called_with(user_id=ANONYMOUS_UID, db_engine=None) resp = await client.get(url.with_query(start=0, count=2)) payload = await resp.json() assert resp.status == 200, payload projects, error = unwrap_envelope(payload) assert not error assert projects mock.assert_called_with(user_id=ANONYMOUS_UID, db_engine=None) assert len(projects) == 1 assert projects[0] == fake_project
async def test_check_health(docker_stack, client): resp = await client.get("/%s/" % API_VERSION) payload = await resp.json() assert resp.status == 200, str(payload) data, error = unwrap_envelope(payload) assert data assert not error assert data['name'] == 'simcore_service_webserver' assert data['status'] == 'SERVICE_RUNNING'
async def test_update_pipeline(docker_stack, client, project_id:str, mock_workbench_payload, mock_workbench_adjacency_list, postgres_session): resp = await client.put("/{}/computation/pipeline/{}".format(API_VERSION, project_id), json = mock_workbench_payload, ) assert resp.status == 204, str(await resp.text()) payload = await resp.json() data, error = unwrap_envelope(payload) assert not data assert not error # check db comp_pipeline _check_db_contents(project_id, postgres_session, mock_workbench_payload, mock_workbench_adjacency_list, check_outputs=True)
async def security_cookie(client) -> str: # get the cookie by calling the root entrypoint resp = await client.get("/v0/") payload = await resp.json() assert resp.status == 200, str(payload) data, error = unwrap_envelope(payload) assert data assert not error cookie = "" if "Cookie" in resp.request_info.headers: cookie = resp.request_info.headers["Cookie"] yield cookie
async def _get_user_projects(client): from servicelib.rest_responses import unwrap_envelope url = client.app.router["list_projects"].url_for() resp = await client.get(url.with_query(type="user")) payload = await resp.json() assert resp.status == 200, payload projects, error = unwrap_envelope(payload) assert not error, pprint(error) return projects
async def test_login_successfully(client): url = client.app.router["auth_login"].url_for() async with NewUser() as user: r = await client.post( url, json={"email": user["email"], "password": user["raw_password"]} ) assert r.status == 200 data, error = unwrap_envelope(await r.json()) assert not error assert data assert cfg.MSG_LOGGED_IN in data["message"]
async def _request_info(self, service_identifier: str): data = {} url = self.base_url / ("running_interactive_services/%s" % service_identifier) # TODO: see if client can cache consecutive calls. SEE self.cli.api_client.last_response is a # https://docs.aiohttp.org/en/stable/client_reference.html#response-object async with self.session.get(url, ssl=False) as resp: payload = await resp.json() data, error = unwrap_envelope(payload) if error: raise RuntimeError(str(error)) return data
async def test_list_template_projects(loop, client, fake_db, fake_template_projects, fake_template_projects_osparc): fake_db.load_template_projects() async with LoggedUser(client): url = client.app.router["list_projects"].url_for() resp = await client.get(url.with_query(type="template")) payload = await resp.json() assert resp.status == 200, pprint(payload) projects, error = unwrap_envelope(payload) assert not error, pprint(error) # fake-template-projects.json + fake-template-projects.osparc.json assert len(projects) == (len(fake_template_projects) + len(fake_template_projects_osparc))
async def test_storage_locations(client, storage_server): url = "/v0/storage/locations" async with LoggedUser(client) as user: print("Logged user:", user) # TODO: can use in the test resp = await client.get(url) payload = await resp.json() assert resp.status == 200, str(payload) data, error = unwrap_envelope(payload) assert len(data) == 1 assert not error assert data[0]['user_id'] == user['id']
async def test_delete(client, logged_user, tokens_db, fake_tokens): sid = fake_tokens[0]['service'] url = client.app.router["delete_token"].url_for(service=sid) assert "/v0/me/tokens/%s" % sid == str(url) resp = await client.delete(url) payload = await resp.json() assert resp.status == 204, payload data, error = unwrap_envelope(payload) assert not error assert not data assert not (await get_token_from_db(tokens_db, token_service=sid))
async def test_start_pipeline(sleeper_service, client, project_id:str, mock_workbench_payload, mock_workbench_adjacency_list, postgres_session, celery_service): # import pdb; pdb.set_trace() resp = await client.post("/{}/computation/pipeline/{}/start".format(API_VERSION, project_id), json = mock_workbench_payload, ) assert resp.status == 200, str(await resp.text()) payload = await resp.json() data, error = unwrap_envelope(payload) assert data assert not error assert "pipeline_name" in data assert "project_id" in data assert data['project_id'] == project_id # check db comp_pipeline _check_db_contents(project_id, postgres_session, mock_workbench_payload, mock_workbench_adjacency_list, check_outputs=False)
async def test_404_not_found(client, specs): # see FIXME: in validate_middleware_factory response = await client.get("/some-invalid-address-outside-api") payload = await response.text() assert response.status == 404, payload api_base = openapi.get_base_path(specs) response = await client.get(api_base + "/some-invalid-address-in-api") payload = await response.json() assert response.status == 404, payload assert is_enveloped(payload) data, error = unwrap_envelope(payload) assert error assert not data
async def test_storage_list_filter(client, storage_server): # tests composition of 2 queries file_id = "a/b/c/d/e/dat" url = "/v0/storage/locations/0/files/metadata?uuid_filter={}".format(quote(file_id, safe='')) async with LoggedUser(client) as user: print("Logged user:", user) # TODO: can use in the test resp = await client.get(url) payload = await resp.json() assert resp.status == 200, str(payload) data, error = unwrap_envelope(payload) assert len(data) == 1 assert not error assert data[0]['uuid_filter'] == file_id
async def test_registration_without_confirmation(client, monkeypatch): monkeypatch.setitem(cfg, 'REGISTRATION_CONFIRMATION_REQUIRED', False) db = get_storage(client.app) url = client.app.router['auth_register'].url_for() r = await client.post(url, json={ 'email': EMAIL, 'password': PASSWORD, 'confirm': PASSWORD }) data, error = unwrap_envelope(await r.json()) assert r.status == 200, (data, error) assert cfg.MSG_LOGGED_IN in data["message"] user = await db.get_user({'email': EMAIL}) assert user await db.delete_user(user)
async def test_storage_file_meta(client, storage_server): # tests redirect of path with quotes in path file_id = "a/b/c/d/e/dat" url = "/v0/storage/locations/0/files/{}/metadata".format(quote(file_id, safe='')) async with LoggedUser(client) as user: print("Logged user:", user) # TODO: can use in the test resp = await client.get(url) payload = await resp.json() assert resp.status == 200, str(payload) data, error = unwrap_envelope(payload) assert len(data) == 1 assert not error assert data[0]['filemeta'] == 42