# Path: invenio_oauthclient/_compat.py
# def monkey_patch_werkzeug():
# 
# Path: invenio_oauthclient/contrib/github.py
# @oauth_error_handler
# def authorized(resp, remote):
#     """Authorized callback handler for GitHub.
# 
#     :param resp: The response.
#     :param remote: The remote application.
#     """
#     if resp and 'error' in resp:
#         if resp['error'] == 'bad_verification_code':
#             # See https://developer.github.com/v3/oauth/#bad-verification-code
#             # which recommends starting auth flow again.
#             return redirect(url_for('invenio_oauthclient.login',
#                                     remote_app='github'))
#         elif resp['error'] in ['incorrect_client_credentials',
#                                'redirect_uri_mismatch']:
#             raise OAuthResponseError(
#                 'Application mis-configuration in GitHub', remote, resp
#             )
# 
#     return authorized_signup_handler(resp, remote)
# 
# Path: invenio_oauthclient/errors.py
# class OAuthResponseError(OAuthError):
#     """Define response exception during OAuth process."""
# 
#     def __init__(self, message, remote, response):
#         """Initialize exception.
# 
#         :param message: Error message.
#         :param remote: Remote application.
#         :param response: OAuth response object.
#         """
#         super(OAuthResponseError, self).__init__(message, remote)
#         self.response = response
# 
# Path: invenio_oauthclient/views/client.py
# def post_ext_init(state):
# def auto_redirect_login(*args, **kwargs):
# def _login(remote_app, authorized_view_name):
# def login(remote_app):
# def rest_login(remote_app):
# def _authorized(remote_app=None):
# def authorized(remote_app=None):
# def rest_authorized(remote_app=None):
# def _signup(remote_app):
# def signup(remote_app):
# def rest_signup(remote_app):
# def _disconnect(remote_app):
# def disconnect(remote_app):
# def rest_disconnect(remote_app):


from collections import namedtuple
from flask import session, url_for
from flask_login import current_user
from flask_security import login_user
from flask_security.utils import hash_password
from helpers import check_redirect_location, mock_response
from invenio_accounts.models import User
from invenio_db import db
from six.moves.urllib_parse import parse_qs, urlparse
from invenio_oauthclient._compat import _create_identifier
from invenio_oauthclient.contrib.github import authorized
from invenio_oauthclient.errors import OAuthResponseError
from invenio_oauthclient.models import RemoteAccount, RemoteToken, UserIdentity
from invenio_oauthclient.views.client import serializer
import mock
import pytest

def test_not_authenticated(app):
    """Test disconnect when user is not authenticated."""
    with app.test_client() as client:
        assert not current_user.is_authenticated
        resp = client.get(
            url_for('invenio_oauthclient.disconnect', remote_app='github'))
        assert resp.status_code == 302


def test_authorized_handler(app, remote):
    """Test authorized callback handler."""
    # General error
    example_response = {'error': 'error'}
    resp = authorized(example_response, remote)
    check_redirect_location(resp, '/')

    # Bad verification error
    example_response = {'error': 'bad_verification_code'}
    resp = authorized(example_response, remote)
    check_redirect_location(resp, '/oauth/login/github/')

    # Incorrect client credentials
    example_response = {'error': 'incorrect_client_credentials'}
    with pytest.raises(OAuthResponseError):
        authorized(example_response, remote)

        # Redirect uri mismatch
        example_response = {'error': 'redirect_uri_mismatch'}
        with pytest.raises(OAuthResponseError):

# Path: invenio_oauthclient/_compat.py
# def monkey_patch_werkzeug():
# 
# Path: invenio_oauthclient/contrib/github.py
# @oauth_error_handler
# def authorized(resp, remote):
#     """Authorized callback handler for GitHub.
# 
#     :param resp: The response.
#     :param remote: The remote application.
#     """
#     if resp and 'error' in resp:
#         if resp['error'] == 'bad_verification_code':
#             # See https://developer.github.com/v3/oauth/#bad-verification-code
#             # which recommends starting auth flow again.
#             return redirect(url_for('invenio_oauthclient.login',
#                                     remote_app='github'))
#         elif resp['error'] in ['incorrect_client_credentials',
#                                'redirect_uri_mismatch']:
#             raise OAuthResponseError(
#                 'Application mis-configuration in GitHub', remote, resp
#             )
# 
#     return authorized_signup_handler(resp, remote)
# 
# Path: invenio_oauthclient/errors.py
# class OAuthResponseError(OAuthError):
#     """Define response exception during OAuth process."""
# 
#     def __init__(self, message, remote, response):
#         """Initialize exception.
# 
#         :param message: Error message.
#         :param remote: Remote application.
#         :param response: OAuth response object.
#         """
#         super(OAuthResponseError, self).__init__(message, remote)
#         self.response = response
# 
# Path: invenio_oauthclient/views/client.py
# def post_ext_init(state):
# def auto_redirect_login(*args, **kwargs):
# def _login(remote_app, authorized_view_name):
# def login(remote_app):
# def rest_login(remote_app):
# def _authorized(remote_app=None):
# def authorized(remote_app=None):
# def rest_authorized(remote_app=None):
# def _signup(remote_app):
# def signup(remote_app):
# def rest_signup(remote_app):
# def _disconnect(remote_app):
# def disconnect(remote_app):
# def rest_disconnect(remote_app):


# Path: tests/test_contrib_github.py
from collections import namedtuple
from flask import session, url_for
from flask_login import current_user
from flask_security import login_user
from flask_security.utils import hash_password
from helpers import check_redirect_location, mock_response
from invenio_accounts.models import User
from invenio_db import db
from six.moves.urllib_parse import parse_qs, urlparse
from invenio_oauthclient._compat import _create_identifier
from invenio_oauthclient.contrib.github import authorized
from invenio_oauthclient.errors import OAuthResponseError
from invenio_oauthclient.models import RemoteAccount, RemoteToken, UserIdentity
from invenio_oauthclient.views.client import serializer
import mock
import pytest


def test_not_authenticated(app):
    """Test disconnect when user is not authenticated."""
    with app.test_client() as client:
        assert not current_user.is_authenticated
        resp = client.get(
            url_for('invenio_oauthclient.disconnect', remote_app='github'))
        assert resp.status_code == 302


def test_authorized_handler(app, remote):
    """Test authorized callback handler."""
    # General error
    example_response = {'error': 'error'}
    resp = authorized(example_response, remote)
    check_redirect_location(resp, '/')

    # Bad verification error
    example_response = {'error': 'bad_verification_code'}
    resp = authorized(example_response, remote)
    check_redirect_location(resp, '/oauth/login/github/')

    # Incorrect client credentials
    example_response = {'error': 'incorrect_client_credentials'}
    with pytest.raises(OAuthResponseError):
        authorized(example_response, remote)

        # Redirect uri mismatch
        example_response = {'error': 'redirect_uri_mismatch'}
        with pytest.raises(OAuthResponseError):

            authorized(example_response, remote)