# Path: invenio_oauthclient/contrib/cern_openid.py
# OAUTHCLIENT_CERN_OPENID_SESSION_KEY = "identity.cern_openid_provides"
# 
# def account_info(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)
#         flash(_("CERN account not allowed."), category="danger")
#         return redirect("/")
# 
# def disconnect_handler(remote, *args, **kwargs):
#     """Handle unlinking of remote account."""
#     _disconnect(remote, *args, **kwargs)
#     return redirect(url_for("invenio_oauthclient_settings.index"))
# 
# 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 flask import g, session, url_for
from flask_security import login_user, logout_user
from flask_security.utils import hash_password
from helpers import 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, disconnect_handler, \
    fetch_extra_data, get_dict_from_response
from flask_oauthlib.client import OAuthResponse  # noqa isort:skip
    from jwt import encode
        assert resp.status_code == 302
        assert resp.location == ('http://localhost/account/settings/'
                                 'linkedaccounts/')
        assert len(g.identity.provides) == 3

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

    with app.test_request_context():
        resp = disconnect_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(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)
#         flash(_("CERN account not allowed."), category="danger")
#         return redirect("/")
# 
# def disconnect_handler(remote, *args, **kwargs):
#     """Handle unlinking of remote account."""
#     _disconnect(remote, *args, **kwargs)
#     return redirect(url_for("invenio_oauthclient_settings.index"))
# 
# 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.py
import os
import pytest
from flask import g, session, url_for
from flask_security import login_user, logout_user
from flask_security.utils import hash_password
from helpers import 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, disconnect_handler, \
    fetch_extra_data, get_dict_from_response
from flask_oauthlib.client import OAuthResponse  # noqa isort:skip
    from jwt import encode

        assert resp.status_code == 302
        assert resp.location == ('http://localhost/account/settings/'
                                 'linkedaccounts/')
        assert len(g.identity.provides) == 3

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

    with app.test_request_context():
        resp = disconnect_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_handler(ioc.remote_apps['cern_openid'])