
# Copyright (C) 2010-2023 RhodeCode GmbH
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License, version 3
# (only), as published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
# This program is dual-licensed. If you wish to learn more about the
# RhodeCode Enterprise Edition, including its added features, Support services,
# and proprietary license terms, please see https://rhodecode.com/licenses/

import mock
import pytest

from rhodecode.lib.utils2 import safe_str
from rhodecode.model.db import (
    RhodeCodeUi, RepoRhodeCodeUi, RhodeCodeSetting, RepoRhodeCodeSetting)
from rhodecode.model.meta import Session
from rhodecode.model.settings import SettingsModel, SettingNotFound, UiSetting


class TestRepoGetUiByKey(object):
    def test_ui_settings_are_returned_when_key_is_found(
            self, repo_stub, settings_util):
        section = 'test section'
        value = 'test value'

        settings_util.create_repo_rhodecode_ui(
            repo_stub, 'wrong section', 'wrong value')
        setting = settings_util.create_repo_rhodecode_ui(
            repo_stub, section, value)
        key = setting.ui_key

        model = SettingsModel(repo=repo_stub.repo_name)
        result = model.get_ui_by_key(key)
        assert result.ui_value == value
        assert result.ui_section == section
        assert result.ui_active is True

    def test_none_is_returned_when_key_is_not_found(
            self, repo_stub, settings_util):
        settings_util.create_repo_rhodecode_ui(
            repo_stub, 'wrong section', 'wrong value')

        model = SettingsModel(repo=repo_stub.repo_name)
        result = model.get_ui_by_key('abcde')
        assert result is None


class TestGlobalGetUiByKey(object):
    def test_ui_settings_are_returned_when_key_is_found(self, settings_util):
        section = 'test section'
        value = 'test value'

        settings_util.create_rhodecode_ui('wrong section', 'wrong value')
        setting = settings_util.create_rhodecode_ui(section, value)
        key = setting.ui_key

        model = SettingsModel()
        result = model.get_ui_by_key(key)
        assert result.ui_value == value
        assert result.ui_section == section
        assert result.ui_active is True

    def test_none_is_returned_when_key_is_not_found(self, settings_util):
        settings_util.create_rhodecode_ui('wrong section', 'wrong value')
        model = SettingsModel()
        result = model.get_ui_by_key('abcde')
        assert result is None


class TestRepoGetUiBySection(object):
    def test_ui_settings_are_returned_when_section_is_found(
            self, repo_stub, settings_util):
        section = 'test section'
        values = ['test value 1', 'test value 2']

        expected_pairs = []
        for value in values:
            setting = settings_util.create_repo_rhodecode_ui(
                repo_stub, section, value)
            expected_pairs.append((setting.ui_key, value))

        model = SettingsModel(repo=repo_stub.repo_name)
        result = model.get_ui_by_section(section)
        result_pairs = [(r.ui_key, r.ui_value) for r in result]
        assert sorted(result_pairs) == sorted(expected_pairs)

    def test_empty_list_is_returned_when_section_is_not_found(
            self, repo_stub, settings_util):
        settings_util.create_repo_rhodecode_ui(
            repo_stub, 'wrong section', 'wrong value')

        model = SettingsModel(repo=repo_stub.repo_name)
        result = model.get_ui_by_section('correct section')
        assert result == []


class TestGlobalGetUiBySection(object):
    def test_ui_settings_are_returned_when_section_is_found(
            self, settings_util):
        section = 'test section'
        values = ['test value 1', 'test value 2']

        expected_pairs = []
        for value in values:
            setting = settings_util.create_rhodecode_ui(section, value)
            expected_pairs.append((setting.ui_key, value))

        model = SettingsModel()
        result = model.get_ui_by_section(section)
        result_pairs = [(r.ui_key, r.ui_value) for r in result]
        assert sorted(result_pairs) == sorted(expected_pairs)

    def test_empty_list_is_returned_when_section_is_not_found(
            self, settings_util):
        settings_util.create_rhodecode_ui('wrong section', 'wrong value')

        model = SettingsModel()
        result = model.get_ui_by_section('correct section')
        assert result == []


class TestRepoGetUiBySectionAndKey(object):
    def test_ui_settings_are_returned_when_section_and_key_are_found(
            self, repo_stub, settings_util):
        section = 'test section'
        value = 'test value'
        key = 'test key'

        settings_util.create_rhodecode_ui(
            'wrong section', 'wrong value', key='wrong key')
        setting = settings_util.create_repo_rhodecode_ui(
            repo_stub, section, value, key=key)
        key = setting.ui_key

        model = SettingsModel(repo=repo_stub.repo_name)
        result = model.get_ui_by_section_and_key(section, key)
        assert result.ui_value == value
        assert result.ui_section == section
        assert result.ui_active is True

    def test_none_is_returned_when_key_section_pair_is_not_found(
            self, repo_stub, settings_util):
        settings_util.create_repo_rhodecode_ui(
            repo_stub, 'section', 'wrong value', key='wrong key')

        model = SettingsModel(repo=repo_stub.repo_name)
        result = model.get_ui_by_section_and_key('section', 'test key')
        assert result is None


class TestGlobalGetUiBySectionAndKey(object):
    def test_ui_settings_are_returned_when_section_and_key_are_found(
            self, settings_util):
        section = 'test section'
        value = 'test value'
        key = 'test key'

        settings_util.create_rhodecode_ui(
            'wrong section', 'wrong value', key='wrong key')
        setting = settings_util.create_rhodecode_ui(section, value, key=key)
        key = setting.ui_key

        model = SettingsModel()
        result = model.get_ui_by_section_and_key(section, key)
        assert result.ui_value == value
        assert result.ui_section == section
        assert result.ui_active is True

    def test_none_is_returned_when_key_section_pair_is_not_found(
            self, settings_util):
        settings_util.create_rhodecode_ui(
            'section', 'wrong value', key='wrong key')
        model = SettingsModel()
        result = model.get_ui_by_section_and_key('section', 'test key')
        assert result is None


class TestRepoGetUi(object):
    def test_non_empty_list_is_returned_when_ui_settings_found(
            self, repo_stub, settings_util, fake_ui_values):
        for ui in fake_ui_values:
            settings_util.create_repo_rhodecode_ui(
                repo_stub, ui.section, ui.value, key=ui.key)
            # Create few global settings to check that only repo ones are
            # displayed
            settings_util.create_rhodecode_ui(ui.section, ui.value, key=ui.key)

        model = SettingsModel(repo=repo_stub.repo_name)
        result = model.get_ui()
        assert sorted(result) == sorted(fake_ui_values)

    def test_settings_filtered_by_section(
            self, repo_stub, settings_util, fake_ui_values):
        for ui in fake_ui_values:
            settings_util.create_repo_rhodecode_ui(
                repo_stub, ui.section, ui.value, key=ui.key)

        model = SettingsModel(repo=repo_stub.repo_name)
        result = model.get_ui(section=fake_ui_values[0].section)
        expected_result = [
            s for s in fake_ui_values
            if s.section == fake_ui_values[0].section]
        assert sorted(result) == sorted(expected_result)

    def test_settings_filtered_by_key(
            self, repo_stub, settings_util, fake_ui_values):
        for ui in fake_ui_values:
            settings_util.create_repo_rhodecode_ui(
                repo_stub, ui.section, ui.value, key=ui.key)

        model = SettingsModel(repo=repo_stub.repo_name)
        result = model.get_ui(key=fake_ui_values[0].key)
        expected_result = [
            s for s in fake_ui_values if s.key == fake_ui_values[0].key]
        assert sorted(result) == sorted(expected_result)

    def test_empty_list_is_returned_when_ui_settings_are_not_found(
            self, repo_stub, settings_util):
        for i in range(10):
            settings_util.create_rhodecode_ui(
                'section{}'.format(i), 'value{}'.format(i),
                key='key{}'.format(i), active=True)

        model = SettingsModel(repo=repo_stub.repo_name)
        result = model.get_ui()
        assert result == []


class TestGlobalGetUi(object):
    def test_non_empty_list_is_returned_when_ui_settings_found(
            self, backend_stub, settings_util, fake_ui_values):
        repo = backend_stub.create_repo()
        for ui in fake_ui_values:
            settings_util.create_rhodecode_ui(ui.section, ui.value, key=ui.key)
            # Create few repo settings to check that only global ones are
            # displayed
            settings_util.create_repo_rhodecode_ui(
                repo, ui.section, ui.value, key=ui.key)

        model = SettingsModel()
        result = model.get_ui()
        for ui in fake_ui_values:
            assert ui in result

    def test_settings_filtered_by_key(self, settings_util, fake_ui_values):
        for ui in fake_ui_values:
            settings_util.create_rhodecode_ui(ui.section, ui.value, key=ui.key)
        expected_result = [
            s for s in fake_ui_values if s.key == fake_ui_values[0].key]

        model = SettingsModel()
        result = model.get_ui(key=fake_ui_values[0].key)
        assert sorted(result) == sorted(expected_result)

    def test_settings_filtered_by_section(self, settings_util, fake_ui_values):
        for ui in fake_ui_values:
            settings_util.create_rhodecode_ui(ui.section, ui.value, key=ui.key)
        expected_result = [
            s for s in fake_ui_values
            if s.section == fake_ui_values[0].section]

        model = SettingsModel()
        result = model.get_ui(section=fake_ui_values[0].section)
        assert sorted(result) == sorted(expected_result)

    def test_repo_settings_are_not_displayed(
            self, backend_stub, settings_util, fake_ui_values):
        repo = backend_stub.create_repo()
        for ui in fake_ui_values:
            settings_util.create_repo_rhodecode_ui(
                repo, ui.section, ui.value, key=ui.key, active=ui.active)

        model = SettingsModel()
        result = model.get_ui()
        for ui in fake_ui_values:
            assert ui not in result


class TestRepoGetBuiltInHooks(object):
    def test_only_builtin_hooks_are_returned(self, repo_stub, settings_util):
        section = 'hooks'
        valid_keys = SettingsModel.BUILTIN_HOOKS
        invalid_keys = ('fake_hook', )
        keys = valid_keys + invalid_keys

        for key in keys:
            settings_util.create_repo_rhodecode_ui(
                repo_stub, section, 'test value', key=key)

        model = SettingsModel(repo=repo_stub.repo_name)
        result = model.get_builtin_hooks()

        assert len(result) == len(valid_keys)
        for entry in result:
            assert entry.ui_key in valid_keys


class TestGlobalGetBuiltInHooks(object):
    def test_only_builtin_hooks_are_returned(self, settings_util):
        section = 'hooks'
        valid_keys = ('valid_key1', 'valid_key2')
        invalid_keys = ('fake_hook', )
        keys = valid_keys + invalid_keys

        for key in keys:
            settings_util.create_rhodecode_ui(section, 'test value', key=key)

        model = SettingsModel()
        with mock.patch.object(model, 'BUILTIN_HOOKS', valid_keys):
            result = model.get_builtin_hooks()

        assert len(result) == len(valid_keys)
        for entry in result:
            assert entry.ui_key in valid_keys


class TestRepoGetCustomHooks(object):
    def test_only_custom_hooks_are_returned(self, repo_stub, settings_util):
        section = 'hooks'
        valid_keys = ('custom', )
        invalid_keys = SettingsModel.BUILTIN_HOOKS
        keys = valid_keys + invalid_keys

        for key in keys:
            settings_util.create_repo_rhodecode_ui(
                repo_stub, section, 'test value', key=key)

        model = SettingsModel(repo=repo_stub.repo_name)
        result = model.get_custom_hooks()

        assert len(result) == len(valid_keys)
        for entry in result:
            assert entry.ui_key in valid_keys


class TestGlobalGetCustomHooks(object):
    def test_only_custom_hooks_are_returned(self, settings_util):
        section = 'hooks'
        valid_keys = ('valid_key1', 'valid_key2')
        invalid_keys = ('fake_hook', )
        keys = valid_keys + invalid_keys

        for key in keys:
            settings_util.create_rhodecode_ui(section, 'test value', key=key)

        model = SettingsModel()
        with mock.patch.object(model, 'BUILTIN_HOOKS', invalid_keys):
            result = model.get_custom_hooks()
        for entry in result:
            assert entry.ui_key not in invalid_keys


class TestRepoCreateUiSectionValue(object):
    @pytest.mark.parametrize("additional_kwargs", [
        {'key': 'abcde'},
        {'active': False},
        {}
    ])
    def test_ui_section_value_is_created(
            self, repo_stub, additional_kwargs):
        model = SettingsModel(repo=repo_stub.repo_name)
        section = 'test section'
        value = 'test value'
        result = model.create_ui_section_value(section, value)
        key = result.ui_key
        Session().commit()

        setting = model.get_ui_by_key(key)
        try:
            assert setting == result
            assert isinstance(setting, RepoRhodeCodeUi)
        finally:
            Session().delete(result)
            Session().commit()


class TestGlobalCreateUiSectionValue(object):
    @pytest.mark.parametrize("additional_kwargs", [
        {'key': 'abcde'},
        {'active': False},
        {}
    ])
    def test_ui_section_value_is_created_with_autogenerated_key(
            self, backend_stub, additional_kwargs):
        model = SettingsModel()
        section = 'test section'
        value = 'test value'
        result = model.create_ui_section_value(
            section, value, **additional_kwargs)
        key = result.ui_key
        Session().commit()

        setting = model.get_ui_by_key(key)
        try:
            assert setting == result
            assert isinstance(setting, RhodeCodeUi)
        finally:
            Session().delete(result)
            Session().commit()


class TestRepoCreateOrUpdateHook(object):
    def test_hook_created(self, repo_stub):
        model = SettingsModel(repo=repo_stub.repo_name)
        key = 'test_key'
        value = 'test value'
        result = model.create_or_update_hook(key, value)
        Session().commit()

        setting = model.get_ui_by_section_and_key('hooks', key)
        try:
            assert setting == result
            assert isinstance(setting, RepoRhodeCodeUi)
        finally:
            Session().delete(result)
            Session().commit()

    def test_hook_updated(self, repo_stub, settings_util):
        section = 'hooks'
        key = 'test_key'

        settings_util.create_repo_rhodecode_ui(
            repo_stub, section, 'old value', key=key)

        model = SettingsModel(repo=repo_stub.repo_name)
        value = 'test value'
        model.create_or_update_hook(key, value)
        Session().commit()

        setting = model.get_ui_by_section_and_key('hooks', key)
        assert setting.ui_value == value


class TestGlobalCreateOrUpdateHook(object):
    def test_hook_created(self):
        model = SettingsModel()
        key = 'test_key'
        value = 'test value'
        result = model.create_or_update_hook(key, value)
        Session().commit()

        setting = model.get_ui_by_section_and_key('hooks', key)
        try:
            assert setting == result
            assert isinstance(setting, RhodeCodeUi)
        finally:
            Session().delete(result)
            Session().commit()

    def test_hook_updated(self, settings_util):
        section = 'hooks'
        key = 'test_key'

        settings_util.create_rhodecode_ui(section, 'old value', key=key)

        model = SettingsModel()
        value = 'test value'
        model.create_or_update_hook(key, value)
        Session().commit()

        setting = model.get_ui_by_section_and_key('hooks', key)
        assert setting.ui_value == value


class TestDeleteUiValue(object):
    def test_delete_ui_when_repo_is_set(self, repo_stub, settings_util):
        model = SettingsModel(repo=repo_stub.repo_name)
        result = settings_util.create_repo_rhodecode_ui(
            repo_stub, 'section', None, cleanup=False)

        key = result.ui_key
        model.delete_ui(result.ui_id)
        Session().commit()

        setting = model.get_ui_by_key(key)
        assert setting is None

    @pytest.mark.parametrize('id_', (None, 123))
    def test_raises_exception_when_id_is_not_specified(self, id_):
        model = SettingsModel()
        with pytest.raises(SettingNotFound) as exc_info:
            model.delete_ui(id_)
        assert str(exc_info.value) == 'Setting `{}` is not found'.format(id_)

    def test_delete_ui_when_repo_is_not_set(self, settings_util):
        model = SettingsModel()
        result = settings_util.create_rhodecode_ui(
            'section', None, cleanup=False)

        key = result.ui_key
        model.delete_ui(result.ui_id)
        Session().commit()

        setting = model.get_ui_by_key(key)
        assert setting is None


class TestRepoGetSettingByName(object):
    @pytest.mark.parametrize("name, value, type_, expected_value", [
        ('test_unicode', 'Straße', 'unicode', 'Straße'),
        ('test_int', '1234', 'int', 1234),
        ('test_bool', 'True', 'bool', True),
        ('test_list', 'a,b,c', 'list', ['a', 'b', 'c'])
    ])
    def test_setting_is_returned_when_name_is_found(
            self, repo_stub, settings_util, name, value, type_,
            expected_value):
        settings_util.create_repo_rhodecode_setting(
            repo_stub, name, value, type_)

        model = SettingsModel(repo=repo_stub.repo_name)
        setting = model.get_setting_by_name(name)
        assert setting.app_settings_type == type_
        actual_value = setting.app_settings_value
        if type_ == 'unicode':
            actual_value = safe_str(actual_value)
        assert actual_value == expected_value

    def test_returns_none_if_the_setting_does_not_exist(self, repo_stub):
        model = SettingsModel(repo=repo_stub.repo_name)
        setting = model.get_setting_by_name('abcde')
        assert setting is None


class TestGlobalGetSettingByName(object):
    @pytest.mark.parametrize("name, value, type_, expected_value", [
        ('test_unicode', 'Straße', 'unicode', 'Straße'),
        ('test_int', '1234', 'int', 1234),
        ('test_bool', 'True', 'bool', True),
        ('test_list', 'a,b,c', 'list', ['a', 'b', 'c'])
    ])
    def test_setting_is_returned_when_name_is_found(
            self, settings_util, name, value, type_, expected_value):
        settings_util.create_rhodecode_setting(name, value, type_)

        model = SettingsModel()
        setting = model.get_setting_by_name(name)
        assert setting.app_settings_type == type_
        actual_value = setting.app_settings_value
        if type_ == 'unicode':
            actual_value = safe_str(actual_value)
        assert actual_value == expected_value

    def test_returns_none_if_the_setting_does_not_exist(self):
        model = SettingsModel()
        setting = model.get_setting_by_name('abcde')
        assert setting is None


class TestRepoGetAllSettings(object):
    def test_settings_are_found(self, repo_stub, settings_util):
        initial_settings = {
            'test_setting_{}'.format(i): 'value' for i in range(10)}
        settings = [
            settings_util.create_repo_rhodecode_setting(
                repo_stub, name, initial_settings[name], 'unicode')
            for name in initial_settings
        ]
        model = SettingsModel(repo=repo_stub.repo_name)

        settings = model.get_all_settings()
        expected_settings = {
            'rhodecode_' + name: initial_settings[name]
            for name in initial_settings
        }

        assert len(settings) == 10
        assert expected_settings == settings

    def test_settings_are_not_found(self, repo_stub):
        model = SettingsModel(repo=repo_stub.repo_name)
        setting = model.get_all_settings()
        assert setting == {}


class TestGlobalGetAllSettings(object):
    def test_settings_are_found(self, settings_util):
        initial_settings = {
            'test_setting_{}'.format(i): 'value' for i in range(10)}
        settings = [
            settings_util.create_rhodecode_setting(
                name, initial_settings[name], 'unicode')
            for name in initial_settings
        ]
        model = SettingsModel()

        settings = model.get_all_settings()
        expected_settings = {
            'rhodecode_' + name: initial_settings[name]
            for name in initial_settings
        }

        filtered_settings = {
            name: settings[name]
            for name in settings if name.startswith('rhodecode_test_setting')
        }
        assert len(filtered_settings) == 10
        assert expected_settings == filtered_settings

    def test_settings_are_not_found(self, repo_stub):
        model = SettingsModel(repo=repo_stub.repo_name)
        setting = model.get_all_settings()
        assert setting == {}


class TestRepoCreateOrUpdateSetting(object):
    def test_setting_is_created(self, repo_stub):
        model = SettingsModel(repo=repo_stub.repo_name)
        name = 'test_setting'
        value = 'test_value'
        model.create_or_update_setting(name, val=value)

        setting = model.get_setting_by_name(name)
        try:
            assert setting.app_settings_name == name
            assert setting.app_settings_value == value
            assert setting.app_settings_type == 'unicode'
            assert isinstance(setting, RepoRhodeCodeSetting)
        finally:
            Session().delete(setting)
            Session().commit()

    def test_setting_is_updated(self, repo_stub, settings_util):
        model = SettingsModel(repo=repo_stub.repo_name)
        name = 'test_setting'
        value = 'test_value'
        settings_util.create_repo_rhodecode_setting(
            repo_stub, name, value, 'unicode', cleanup=False)

        updated_value = 'test_value_2'
        model.create_or_update_setting(name, val=updated_value)

        setting = model.get_setting_by_name(name)
        try:
            assert setting.app_settings_name == name
            assert setting.app_settings_value == updated_value
            assert setting.app_settings_type == 'unicode'
            assert isinstance(setting, RepoRhodeCodeSetting)
        finally:
            Session().delete(setting)
            Session().commit()


class TestGlobalCreateOrUpdateSetting(object):
    def test_setting_is_created(self):
        model = SettingsModel()
        name = 'test_setting'
        value = 'test_value'
        model.create_or_update_setting(name, val=value)

        setting = model.get_setting_by_name(name)
        try:
            assert setting.app_settings_name == name
            assert setting.app_settings_value == value
            assert setting.app_settings_type == 'unicode'
            assert isinstance(setting, RhodeCodeSetting)
        finally:
            Session().delete(setting)
            Session().commit()

    def test_setting_is_updated(self, settings_util):
        model = SettingsModel()
        name = 'test_setting'
        value = 'test_value'
        settings_util.create_rhodecode_setting(
            name, value, 'unicode', cleanup=False)

        updated_value = 'test_value_2'
        model.create_or_update_setting(name, val=updated_value)

        setting = model.get_setting_by_name(name)
        try:
            assert setting.app_settings_name == name
            assert setting.app_settings_value == updated_value
            assert setting.app_settings_type == 'unicode'
            assert isinstance(setting, RhodeCodeSetting)
        finally:
            Session().delete(setting)
            Session().commit()


class TestRepoGetAuthSettings(object):
    def test_settings_prefixed_with_auth_are_retured(
            self, repo_stub, settings_util):
        model = SettingsModel(repo=repo_stub.repo_name)
        valid_settings = ('auth_test1', 'auth_test2')
        invalid_settings = ('test1', 'test2')
        fake_value = 'test_value'

        for name in valid_settings + invalid_settings:
            settings_util.create_repo_rhodecode_setting(
                repo_stub, name, fake_value, 'unicode')

        auth_settings = model.get_auth_settings()
        assert auth_settings == {name: fake_value for name in valid_settings}


class TestGlobalGetAuthSettings(object):
    def test_settings_prefixed_with_auth_are_retured(self, settings_util):
        model = SettingsModel()
        valid_settings = ('auth_test1', 'auth_test2')
        invalid_settings = ('test1', 'test2')
        fake_value = 'test_value'

        for name in valid_settings + invalid_settings:
            settings_util.create_rhodecode_setting(name, fake_value, 'unicode')

        auth_settings = model.get_auth_settings()
        for name in auth_settings:
            assert name not in invalid_settings
            if name in valid_settings:
                assert auth_settings[name] == fake_value


class TestGetAuthPlugins(object):
    def test_get_setting_by_name_is_called(self):
        model = SettingsModel()

        fake_value = 'some value'
        result_mock = mock.Mock()
        result_mock.app_settings_value = fake_value

        get_setting_patch = mock.patch.object(
            model, 'get_setting_by_name', return_value=result_mock)

        with get_setting_patch as get_setting_mock:
            result = model.get_auth_plugins()

        get_setting_mock.assert_called_once_with('auth_plugins')
        assert result == fake_value


class TestDefaultRepoSettings(object):
    DEFAULT_SETTINGS_NAMES = ['default_a{}'.format(i) for i in range(10)]
    CUSTOM_SETTINGS_NAMES = ['setting_b_{}'.format(i) for i in range(10)]

    def test_returns_global_settings_prefixed_with_default(
            self, settings_util):
        self._create_values(settings_util)
        model = SettingsModel()
        result = model.get_default_repo_settings()
        self._assert_prefixed_settings(result)

    def test_returns_global_settings_without_default_prefix(
            self, settings_util):
        self._create_values(settings_util)
        model = SettingsModel()
        result = model.get_default_repo_settings(strip_prefix=True)
        self._assert_non_prefixed_settings(result)

    def test_returns_per_repo_settings_prefixed_with_default(
            self, repo_stub, settings_util):
        model = SettingsModel(repo=repo_stub)
        self._create_values(settings_util, repo=repo_stub)
        result = model.get_default_repo_settings()
        self._assert_prefixed_settings(result)

    def test_returns_per_repo_settings_without_default_prefix(
            self, repo_stub, settings_util):
        model = SettingsModel(repo=repo_stub)
        self._create_values(settings_util, repo=repo_stub)
        result = model.get_default_repo_settings(strip_prefix=True)
        self._assert_non_prefixed_settings(result)

    def _create_values(self, settings_util, repo=None):
        for name in self.DEFAULT_SETTINGS_NAMES + self.CUSTOM_SETTINGS_NAMES:
            if not repo:
                settings_util.create_rhodecode_setting(
                    name, 'value', 'unicode')
            else:
                settings_util.create_repo_rhodecode_setting(
                    repo, name, 'value', 'unicode')

    def _assert_prefixed_settings(self, result):
        for setting in self.DEFAULT_SETTINGS_NAMES:
            assert setting in result
            assert result[setting] == 'value'

        for setting in self.CUSTOM_SETTINGS_NAMES:
            assert setting not in result

    def _assert_non_prefixed_settings(self, result):
        for setting in self.DEFAULT_SETTINGS_NAMES:
            setting = setting.replace('default_', '')
            assert setting in result
            assert result[setting] == 'value'


@pytest.fixture()
def fake_ui_values():
    return [
        UiSetting(
            'section{}'.format(i % 2), 'key{}'.format(i),
            'value{}'.format(i), True)
        for i in range(10)
    ]
