import jwt
from datetime import datetime, timedelta
from ..handlers.auth import JWT_ALG


def test_no_access_without_token(client, user):
    resp = client.get('/users/%s' % user.id, raw=True)
    assert resp.get_json()['status'] == 401
    assert resp.get_json()['detail'] == 'No authorization token provided'


def test_no_access_with_bad_token(client, user):
    bad_token = 'foo'
    resp = client.get('/users/%s' % user.id, raw=True,
                      headers={'Authorization': 'Bearer %s' % bad_token})
    assert resp.get_json()['status'] == 401
    assert 'wrong credentials' in resp.get_json()['detail']


def test_no_access_with_incorrectly_signed_token(client, user):
    bad_secret = 'secret'
    bad_token = jwt.encode({
        'iat': datetime.utcnow(),
        'exp': datetime.utcnow() + timedelta(days=7),
        'sub': user.id,
    }, bad_secret, algorithm=JWT_ALG)
    resp = client.get('/users/%s' % user.id, raw=True,
                      headers={'Authorization': 'Bearer %s' % bad_token})
    assert resp.get_json()['status'] == 401
    assert 'wrong credentials' in resp.get_json()['detail']


def test_login(client, user):
    resp = client.post('/users/login', json=dict(
        username=user.username, password=user.original_password
    ))

    assert 'token' in resp.keys()
    assert resp['user_id'] == user.id

    resp = client.get('/users/%s' % user.id,
                      headers={'Authorization': 'Bearer %s' % resp['token']})
    assert resp['id'] == user.id


def test_login_fails_with_bad_username(client, user):
    resp = client.post('/users/login', raw=True, json=dict(
        username='foo', password=user.original_password
    ))
    assert resp.status_code == 401
    assert 'Could not authenticate' in resp.get_json()['error']


def test_login_fails_with_bad_password(client, user):
    resp = client.post('/users/login', raw=True, json=dict(
        username=user.username, password='foo'
    ))
    assert resp.status_code == 401
    assert 'Could not authenticate' in resp.get_json()['error']
