# coding: utf-8
from django.test import TestCase
from corehq.apps.app_manager.commcare_settings import SETTINGS_LOOKUP, SETTINGS
from corehq.apps.app_manager.models import Application
from corehq.apps.app_manager.tests.util import TestFileMixin
import xml.etree.ElementTree as ET

from corehq.apps.builds.models import BuildSpec
from corehq import toggles


class ProfileTest(TestCase, TestFileMixin):
    file_path = ('data',)

    def setUp(self):
        self.app = Application(build_spec=BuildSpec(
            version='2.7.0'
            ),
            name=u"TÉST ÁPP",
            domain="potter"
        )
        toggles.CUSTOM_PROPERTIES.set('domain:potter', True)

    def _test_profile(self, app):
        profile = app.create_profile()
        assert isinstance(profile, bytes), type(profile)
        assert u"TÉST ÁPP" in profile.decode('utf-8')
        profile_xml = ET.fromstring(profile)
        types = {
            'features': self._test_feature,
            'properties': self._test_property,
        }
        for p_type, test_method in types.items():
            for key, value in app.profile.get(p_type, {}).items():
                setting = SETTINGS_LOOKUP[p_type][key]
                test_method(profile_xml, key, value, setting)

    def _get_node(self, profile, key, xpath_template):
        xpath = xpath_template.format(key)
        node = profile.find(xpath)
        self.assertIsNotNone(node, 'Node not found: {}.'.format(xpath))
        return node

    def _test_feature(self, profile, key, value, setting):
        node = self._get_node(profile, key, './features/{}')
        self.assertEqual(node.get('active'), value, 'Feature "{}"'.format(key))

    def _test_property(self, profile, key, value, setting):
        node = self._get_node(profile, key, "./property[@key='{}']")
        self.assertEqual(node.get('value'), value, 'Property "{}"'.format(key))

        force = setting.get('force', False)
        force_actual = node.get('force')
        if not force:
            self.assertIn(
                force_actual,
                [None, 'false'],
                '"force" incorrect for property "{}"'.format(key)
            )
        else:
            self.assertEqual(
                force_actual,
                'true',
                '"force" incorrect for property "{}"'.format(key)
            )

    def _test_custom_property(self, profile, key, value):
        node = self._get_node(profile, key, "./property[@key='{}']")
        self.assertEqual(node.get('value'), value, 'Property "{}"'.format(key))

        force_actual = node.get('force')
        self.assertEqual(
            force_actual,
            'true',
            '"force" should always be true for custom properties"{}"'.format(key)
        )

    def test_profile_properties(self):
        for setting in SETTINGS:
            if setting['id'] == 'users':
                continue
            for value in setting.get('values', []):
                self.app.profile = {
                    setting['type']: {
                        setting['id']: value
                    }
                }
                self._test_profile(self.app)

        # custom properties do not rely on SETTINGS so need to be tested separately
        self.app.profile = {
            'custom_properties': {
                'random': 'value'
            }
        }
        profile = self.app.create_profile()
        self._test_profile(self.app)
        self._test_custom_property(ET.fromstring(profile), 'random', 'value')

    def test_version(self):
        profile_xml = ET.fromstring(self.app.create_profile())
        root = profile_xml.find('.')
        self.assertEqual(root.get('requiredMajor'), '2')
        self.assertEqual(root.get('requiredMinor'), '7')

@@ -29,24 +29,30 @@
 test import 
+Simple
 TestCase%0Afro
@@ -355,16 +355,65 @@
 toggles%0A
+from toggle.shortcuts import update_toggle_cache%0A
 %0A%0Aclass 
@@ -424,16 +424,22 @@
 ileTest(
+Simple
 TestCase
@@ -668,24 +668,25 @@
       )%0A
+%0A
         
 toggles.
@@ -677,16 +677,36 @@
         
+update_toggle_cache(
 toggles.
@@ -728,19 +728,14 @@
 ES.s
-et('domain:
+lug, '
 pott
@@ -743,16 +743,26 @@
 r', True
+, 'domain'
 )%0A%0A    d

Use toggle cache