import pytest

from mock import patch

from endpoints.api.search import EntitySearch, LinkExternalEntity
from endpoints.api.test.shared import conduct_api_call
from endpoints.test.shared import client_with_identity

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

from test.fixtures import *


@pytest.fixture(
    params=[
        mock_ldap,
        fake_jwt,
        fake_keystone,
    ]
)
def auth_engine(request):
    return request.param


@pytest.fixture(
    params=[
        False,
        True,
    ]
)
def requires_email(request):
    return request.param


def test_entity_search(auth_engine, requires_email, client):
    with auth_engine(requires_email=requires_email) as auth:
        with patch("endpoints.api.search.authentication", auth):
            # Try an unknown prefix.
            response = conduct_api_call(client, EntitySearch, "GET", params=dict(prefix="unknown"))
            results = response.json["results"]
            assert len(results) == 0

            # Try a known prefix.
            response = conduct_api_call(client, EntitySearch, "GET", params=dict(prefix="cool"))
            results = response.json["results"]
            entity = results[0]
            assert entity["name"] == "cool.user"
            assert entity["kind"] == "external"


def test_link_external_entity(auth_engine, requires_email, client):
    with auth_engine(requires_email=requires_email) as auth:
        with patch("endpoints.api.search.authentication", auth):
            with client_with_identity("devtable", client) as cl:
                # Try an unknown user.
                conduct_api_call(
                    cl,
                    LinkExternalEntity,
                    "POST",
                    params=dict(username="unknownuser"),
                    expected_code=400,
                )

                # Try a known user.
                response = conduct_api_call(
                    cl, LinkExternalEntity, "POST", params=dict(username="cool.user")
                )

                entity = response.json["entity"]
                assert entity["name"] == "cool_user"
                assert entity["kind"] == "user"
