async def test_registration_without_confirmation( client: TestClient, cfg: LoginOptions, db: AsyncpgStorage, mocker, ): mocker.patch( "simcore_service_webserver.login.handlers.get_plugin_settings", return_value=LoginSettings( LOGIN_REGISTRATION_CONFIRMATION_REQUIRED=False, LOGIN_REGISTRATION_INVITATION_REQUIRED=False, ), ) 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 assert_error( response: ClientResponse, expected_cls: Type[HTTPException], expected_msg: str = None, ): data, error = unwrap_envelope(await response.json()) return do_assert_error(data, error, expected_cls, expected_msg)
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 ( "This is a result of disable_static_webserver fixture for product OSPARC" 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 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(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: TestClient, login_options: LoginOptions): url = client.app.router["auth_login"].url_for() async with NewUser(app=client.app) as user: r = await client.post( f"{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 login_options.MSG_LOGGED_IN in data["message"]
async def _get_user_projects(): from servicelib.aiohttp.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 safe_unwrap( resp: web.Response, ) -> Tuple[Optional[Union[Dict[str, Any], List[Dict[str, Any]]]], Optional[Dict]]: if resp.status != 200: body = await resp.text() raise web.HTTPException(reason=f"Unexpected response: '{body}'") payload = await resp.json() if not isinstance(payload, dict): raise web.HTTPException(reason=f"Did not receive a dict: '{payload}'") data, error = unwrap_envelope(payload) return data, error
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_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_registration_with_confirmation( client: TestClient, cfg: LoginOptions, db: AsyncpgStorage, capsys, mocker, ): mocker.patch( "simcore_service_webserver.login.handlers.get_plugin_settings", return_value=LoginSettings( LOGIN_REGISTRATION_CONFIRMATION_REQUIRED=True, LOGIN_REGISTRATION_INVITATION_REQUIRED=False, ), ) 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 ( "This is a result of disable_static_webserver fixture for product OSPARC" 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 assert_status( response: ClientResponse, expected_cls: Type[HTTPException], expected_msg: Optional[str] = None, expected_error_code: Optional[str] = None, include_meta: Optional[bool] = False, include_links: Optional[bool] = False, ) -> Tuple[Dict, ...]: """ Asserts for enveloped responses """ json_response = await response.json() data, error = unwrap_envelope(json_response) assert response.status == expected_cls.status_code, ( f"received {response.status}: ({data},{error})" f", expected {expected_cls.status_code} : {expected_msg or ''}") if issubclass(expected_cls, HTTPError): do_assert_error(data, error, expected_cls, expected_msg, expected_error_code) elif issubclass(expected_cls, 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_value = ( data, error, ) if include_meta: return_value += (json_response.get("_meta"), ) if include_links: return_value += (json_response.get("_links"), ) return return_value
async def assert_status(response: web.Response, expected_cls: web.HTTPException, expected_msg: str = None): data, error = unwrap_envelope(await response.json()) assert ( response.status == expected_cls.status_code ), f"got {response.status}, expected {expected_cls.status_code}:\n data:{data},\n error:{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: 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 copy_data_folders_from_project( app: web.Application, source_project: Dict, destination_project: Dict, nodes_map: Dict, user_id: int, ): # TODO: optimize if project has actualy data or not before doing the call client, api_endpoint = _get_storage_client(app) log.debug("Coying %d nodes", len(nodes_map)) # /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, # NOTE: extends time for copying operation timeout=ClientTimeout(total=TOTAL_TIMEOUT_TO_COPY_DATA_SECS), ) as resp: payload = await resp.json() # FIXME: relying on storage to change the project is not a good idea since # it is not storage responsibility to deal with projects 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 assert_error(response: web.Response, expected_cls: web.HTTPException, expected_msg: str = None): data, error = unwrap_envelope(await response.json()) return do_assert_error(data, error, expected_cls, expected_msg)