# Path: invenio_oauthclient/contrib/cern_openid.py
# OAUTHCLIENT_CERN_OPENID_SESSION_KEY = "identity.cern_openid_provides"
# 
# def account_info_rest(remote, resp):
#     """Retrieve remote account information used to find local user."""
#     try:
#         return _account_info(remote, resp)
#     except OAuthCERNRejectedAccountError as e:
#         current_app.logger.warning(e.message, exc_info=True)
#         remote_app_config = current_app.config["OAUTHCLIENT_REST_REMOTE_APPS"][
#             remote.name
#         ]
#         return response_handler(
#             remote,
#             remote_app_config["error_redirect_url"],
#             payload=dict(message="CERN account not allowed.", code=400),
#         )
# 
# def disconnect_rest_handler(remote, *args, **kwargs):
#     """Handle unlinking of remote account."""
#     _disconnect(remote, *args, **kwargs)
#     redirect_url = current_app.config["OAUTHCLIENT_REST_REMOTE_APPS"][
#         remote.name
#     ]["disconnect_redirect_url"]
#     return response_handler(remote, redirect_url)
# 
# def fetch_extra_data(resource):
#     """Return a dict with extra data retrieved from CERN OAuth."""
#     person_id = resource.get("cern_person_id")
#     return dict(person_id=person_id)
# 
# def get_dict_from_response(response):
#     """Prepare new mapping with 'Value's grouped by 'Type'."""
#     result = {}
#     if getattr(response, "_resp") and response._resp.code > 400:
#         return result
# 
#     for key, value in response.data.items():
#         result.setdefault(key, value)
#     return result


import os
import pytest
from datetime import timedelta
from flask import current_app, g, session, url_for
from flask_login import current_user
from flask_security import login_user, logout_user
from flask_security.utils import hash_password
from helpers import check_response_redirect_url_args, get_state, \
    mock_remote_get, mock_response
from six.moves.urllib_parse import parse_qs, urlparse
from invenio_oauthclient.contrib.cern_openid import \
    OAUTHCLIENT_CERN_OPENID_SESSION_KEY, account_info_rest, \
    disconnect_rest_handler, fetch_extra_data, get_dict_from_response
from invenio_oauthclient.models import RemoteAccount
from flask_oauthlib.client import OAuthResponse  # noqa isort:skip
    from jwt import encode
        }
        check_response_redirect_url_args(resp, expected_url_args)

        assert len(g.identity.provides) == 3

    datastore = app_rest.extensions['invenio-accounts'].datastore
    user = datastore.find_user(email='john.doe@cern.ch')
    user.password = hash_password("1234")
    assert user

    with app_rest.test_request_context():
        resp = disconnect_rest_handler(ioc.remote_apps['cern_openid'])
        assert resp.status_code >= 300

        # simulate login (account_info fetch)
        g.oauth_logged_in_with_remote = ioc.remote_apps['cern_openid']

        login_user(user)
        assert len(g.identity.provides) == 3

        logout_user()
        assert len(g.identity.provides) == 1
        assert "cern_resource" not in session
        assert OAUTHCLIENT_CERN_OPENID_SESSION_KEY not in session

        # Login again to test the disconnect handler
        g.oauth_logged_in_with_remote = ioc.remote_apps['cern_openid']
        login_user(user)
        assert len(g.identity.provides) == 3


# Path: invenio_oauthclient/contrib/cern_openid.py
# OAUTHCLIENT_CERN_OPENID_SESSION_KEY = "identity.cern_openid_provides"
# 
# def account_info_rest(remote, resp):
#     """Retrieve remote account information used to find local user."""
#     try:
#         return _account_info(remote, resp)
#     except OAuthCERNRejectedAccountError as e:
#         current_app.logger.warning(e.message, exc_info=True)
#         remote_app_config = current_app.config["OAUTHCLIENT_REST_REMOTE_APPS"][
#             remote.name
#         ]
#         return response_handler(
#             remote,
#             remote_app_config["error_redirect_url"],
#             payload=dict(message="CERN account not allowed.", code=400),
#         )
# 
# def disconnect_rest_handler(remote, *args, **kwargs):
#     """Handle unlinking of remote account."""
#     _disconnect(remote, *args, **kwargs)
#     redirect_url = current_app.config["OAUTHCLIENT_REST_REMOTE_APPS"][
#         remote.name
#     ]["disconnect_redirect_url"]
#     return response_handler(remote, redirect_url)
# 
# def fetch_extra_data(resource):
#     """Return a dict with extra data retrieved from CERN OAuth."""
#     person_id = resource.get("cern_person_id")
#     return dict(person_id=person_id)
# 
# def get_dict_from_response(response):
#     """Prepare new mapping with 'Value's grouped by 'Type'."""
#     result = {}
#     if getattr(response, "_resp") and response._resp.code > 400:
#         return result
# 
#     for key, value in response.data.items():
#         result.setdefault(key, value)
#     return result


# Path: tests/test_contrib_cern_openid_rest.py
import os
import pytest
from datetime import timedelta
from flask import current_app, g, session, url_for
from flask_login import current_user
from flask_security import login_user, logout_user
from flask_security.utils import hash_password
from helpers import check_response_redirect_url_args, get_state, \
    mock_remote_get, mock_response
from six.moves.urllib_parse import parse_qs, urlparse
from invenio_oauthclient.contrib.cern_openid import \
    OAUTHCLIENT_CERN_OPENID_SESSION_KEY, account_info_rest, \
    disconnect_rest_handler, fetch_extra_data, get_dict_from_response
from invenio_oauthclient.models import RemoteAccount
from flask_oauthlib.client import OAuthResponse  # noqa isort:skip
    from jwt import encode

        }
        check_response_redirect_url_args(resp, expected_url_args)

        assert len(g.identity.provides) == 3

    datastore = app_rest.extensions['invenio-accounts'].datastore
    user = datastore.find_user(email='john.doe@cern.ch')
    user.password = hash_password("1234")
    assert user

    with app_rest.test_request_context():
        resp = disconnect_rest_handler(ioc.remote_apps['cern_openid'])
        assert resp.status_code >= 300

        # simulate login (account_info fetch)
        g.oauth_logged_in_with_remote = ioc.remote_apps['cern_openid']

        login_user(user)
        assert len(g.identity.provides) == 3

        logout_user()
        assert len(g.identity.provides) == 1
        assert "cern_resource" not in session
        assert OAUTHCLIENT_CERN_OPENID_SESSION_KEY not in session

        # Login again to test the disconnect handler
        g.oauth_logged_in_with_remote = ioc.remote_apps['cern_openid']
        login_user(user)
        assert len(g.identity.provides) == 3


        disconnect_rest_handler(ioc.remote_apps['cern_openid'])