
import unittest.mock

import pytest

from terrareg.user_group_namespace_permission_type import UserGroupNamespacePermissionType
from terrareg.auth import AdminApiKeyAuthMethod, NotAuthenticated
from test.unit.terrareg import (
    TerraregUnitTest, mock_models, setup_test_data
)
import terrareg.models
from test import client

test_data = {
    'testnamespace': {
        'id': 1
    }
}

user_group_data = {
    'usergroup': {
        'id': 1,
        'site_admin': False,
        'namespace_permissions': {
            'namespace1': UserGroupNamespacePermissionType.FULL
        }
    }
}

class TestApiTerraregIsAuthenticated(TerraregUnitTest):

    def test_authenticated_site_admin(self, client, mock_models):
        """Test endpoint when user is authenticated."""
        mock_get_current_auth_method = unittest.mock.MagicMock(return_value=AdminApiKeyAuthMethod())
        with unittest.mock.patch('terrareg.auth.AuthFactory.get_current_auth_method', mock_get_current_auth_method):
            res = client.get('/v1/terrareg/auth/admin/is_authenticated')
            assert res.status_code == 200
            assert res.json == {'authenticated': True, 'read_access': True, 'namespace_permissions': {}, 'site_admin': True}

    @setup_test_data(test_data, user_group_data=user_group_data)
    def test_authenticated_with_permissions(self, client, mock_models):
        """Test authenticated with permissions"""
        mock_auth_method = unittest.mock.MagicMock()
        mock_auth_method.is_authenticated.return_value = True
        mock_auth_method.is_admin.return_value = False
        mock_auth_method.get_all_namespace_permissions.return_value = {
            terrareg.models.Namespace('testnamespace'): UserGroupNamespacePermissionType.FULL
        }
        mock_auth_method.can_access_read_api.return_value = True
        mock_get_current_auth_method = unittest.mock.MagicMock(return_value=mock_auth_method)
        with unittest.mock.patch('terrareg.auth.AuthFactory.get_current_auth_method', mock_get_current_auth_method):
            res = client.get('/v1/terrareg/auth/admin/is_authenticated')
            assert res.status_code == 200
            assert res.json == {'authenticated': True, 'read_access': True, 'namespace_permissions': {'testnamespace': 'FULL'}, 'site_admin': False}

    @pytest.mark.parametrize('allow_unauthenticated_access', [
        True,
        False
    ])
    def test_unauthenticated(self, client, mock_models, allow_unauthenticated_access):
        """Test endpoint when user is authenticated."""
        mock_get_current_auth_method = unittest.mock.MagicMock(return_value=NotAuthenticated())
        with unittest.mock.patch('terrareg.auth.AuthFactory.get_current_auth_method', mock_get_current_auth_method), \
                unittest.mock.patch('terrareg.config.Config.ALLOW_UNAUTHENTICATED_ACCESS', allow_unauthenticated_access):
            res = client.get('/v1/terrareg/auth/admin/is_authenticated')
            assert res.status_code == 200
            assert res.json == {
                'authenticated': False,
                'read_access': allow_unauthenticated_access,
                'namespace_permissions': {},
                'site_admin': False
            }
