from typing import Dict, Callable, Any

import pytest

from atheneum import db
from atheneum.model import UserToken
from atheneum.service.transformation_service import (
    BaseTransformer,
    deserialize_model,
    register_transformer,
    serialize_model)
from atheneum.service.user_token_service import UserTokenTransformer


def test_serialize_model():
    user_token = UserToken()
    user_token.token = 'test'
    result = serialize_model(user_token)
    assert result is not None
    assert result['token'] == 'test'


def test_deserialize_model():
    user_token_json = {
        'token': 'test'
    }
    result = deserialize_model(UserToken, user_token_json)
    assert result is not None
    assert result.token == 'test'


def test_registering_two_transformers_of_the_same_type():
    class BadTransformer(BaseTransformer):
        type = UserToken

        def _serializers(self) -> Dict[str, Callable[[], Any]]:
            pass

        def _deserializers(self) -> Dict[str, Callable[[db.Model, Any], None]]:
            pass

    error = None
    with pytest.raises(KeyError) as e_info:
        error = e_info
        register_transformer(BadTransformer)

    assert error is not None
    error_msg = error.value.args[0]
    assert error_msg is not None
    assert UserToken.__name__ in error_msg
    assert UserTokenTransformer.__name__ in error_msg
    assert BadTransformer.__name__ in error_msg