import unittest
from mock import patch

from endpoints.api.search import EntitySearch, LinkExternalEntity
from test.test_api_usage import ApiTestCase, ADMIN_ACCESS_USER

from test.test_ldap import mock_ldap
from test.test_external_jwt_authn import fake_jwt
from test.test_keystone_auth import fake_keystone

class EndToEndAuthMixin:
  def test_entity_search(self):
    with self.get_authentication() as auth:
      with patch('endpoints.api.search.authentication', auth):
        # Try an unknown prefix.
        json_data = self.getJsonResponse(EntitySearch, params=dict(prefix='unknown'))
        results = json_data['results']
        self.assertEquals(0, len(results))

        # Try a known prefix.
        json_data = self.getJsonResponse(EntitySearch, params=dict(prefix='cool'))
        results = json_data['results']
        self.assertEquals(1, len(results))
        self.assertEquals('external', results[0]['kind'])
        self.assertEquals('cool.user', results[0]['name'])

  def test_link_external_entity(self):
    with self.get_authentication() as auth:
      with patch('endpoints.api.search.authentication', auth):
        self.login(ADMIN_ACCESS_USER)

        # Try an unknown user.
        self.postResponse(LinkExternalEntity, params=dict(username='unknownuser'),
                          expected_code=400)

        # Try a known user.
        json_data = self.postJsonResponse(LinkExternalEntity, params=dict(username='cool.user'))
        entity = json_data['entity']
        self.assertEquals('cool_user', entity['name'])
        self.assertEquals('user', entity['kind'])


class TestLDAPEndToEnd(ApiTestCase, EndToEndAuthMixin):
  def get_authentication(self):
    return mock_ldap()

class TestJWTEndToEnd(ApiTestCase, EndToEndAuthMixin):
  def get_authentication(self):
    return fake_jwt()

class TestKeystone3EndToEnd(ApiTestCase, EndToEndAuthMixin):
  def get_authentication(self):
    return fake_keystone(3)

class TestLDAPNoEmailEndToEnd(ApiTestCase, EndToEndAuthMixin):
  def get_authentication(self):
    return mock_ldap(requires_email=False)

class TestJWTNoEmailEndToEnd(ApiTestCase, EndToEndAuthMixin):
  def get_authentication(self):
    return fake_jwt(requires_email=False)

class TestKeystone3NoEmailEndToEnd(ApiTestCase, EndToEndAuthMixin):
  def get_authentication(self):
    return fake_keystone(3, requires_email=False)


if __name__ == '__main__':
  unittest.main()