"""
Tests related to XBlock support API.
"""
from openedx.core.djangolib.testing.utils import CacheIsolationTestCase
from common.djangoapps.xblock_django.api import authorable_xblocks, deprecated_xblocks, disabled_xblocks
from common.djangoapps.xblock_django.models import XBlockConfiguration, XBlockStudioConfiguration, XBlockStudioConfigurationFlag  # lint-amnesty, pylint: disable=line-too-long


class XBlockSupportTestCase(CacheIsolationTestCase):
    """
    Tests for XBlock Support methods.
    """
    def setUp(self):
        super().setUp()

        # Set up XBlockConfigurations for disabled and deprecated states
        block_config = [
            ("poll", True, True),
            ("survey", False, True),
            ("done", True, False),
        ]

        for name, enabled, deprecated in block_config:
            XBlockConfiguration(name=name, enabled=enabled, deprecated=deprecated).save()

        # Set up XBlockStudioConfigurations for studio support level
        studio_block_config = [
            ("poll", "", False, XBlockStudioConfiguration.FULL_SUPPORT),  # FULL_SUPPORT negated by enabled=False
            ("survey", "", True, XBlockStudioConfiguration.UNSUPPORTED),
            ("done", "", True, XBlockStudioConfiguration.FULL_SUPPORT),
            ("problem", "", True, XBlockStudioConfiguration.FULL_SUPPORT),
            ("problem", "multiple_choice", True, XBlockStudioConfiguration.FULL_SUPPORT),
            ("problem", "circuit_schematic_builder", True, XBlockStudioConfiguration.UNSUPPORTED),
            ("problem", "ora1", False, XBlockStudioConfiguration.FULL_SUPPORT),
            ("html", "zoom", True, XBlockStudioConfiguration.PROVISIONAL_SUPPORT),
            ("split_module", "", True, XBlockStudioConfiguration.UNSUPPORTED),
        ]

        for name, template, enabled, support_level in studio_block_config:
            XBlockStudioConfiguration(name=name, template=template, enabled=enabled, support_level=support_level).save()

    def test_deprecated_blocks(self):
        """ Tests the deprecated_xblocks method """

        deprecated_xblock_names = [block.name for block in deprecated_xblocks()]
        self.assertCountEqual(["poll", "survey"], deprecated_xblock_names)

        XBlockConfiguration(name="poll", enabled=True, deprecated=False).save()

        deprecated_xblock_names = [block.name for block in deprecated_xblocks()]
        self.assertCountEqual(["survey"], deprecated_xblock_names)

    def test_disabled_blocks(self):
        """ Tests the disabled_xblocks method """

        disabled_xblock_names = [block.name for block in disabled_xblocks()]
        self.assertCountEqual(["survey"], disabled_xblock_names)

        XBlockConfiguration(name="poll", enabled=False, deprecated=True).save()

        disabled_xblock_names = [block.name for block in disabled_xblocks()]
        self.assertCountEqual(["survey", "poll"], disabled_xblock_names)

    def test_authorable_blocks_empty_model(self):
        """
        Tests authorable_xblocks returns an empty list if XBlockStudioConfiguration table is empty, regardless
        of whether or not XBlockStudioConfigurationFlag is enabled.
        """
        XBlockStudioConfiguration.objects.all().delete()
        assert not XBlockStudioConfigurationFlag.is_enabled()
        assert 0 == len(authorable_xblocks(allow_unsupported=True))
        XBlockStudioConfigurationFlag(enabled=True).save()
        assert 0 == len(authorable_xblocks(allow_unsupported=True))

    def test_authorable_blocks(self):
        """
        Tests authorable_xblocks when name is not specified.
        """
        authorable_xblock_names = [block.name for block in authorable_xblocks()]
        self.assertCountEqual(["done", "problem", "problem", "html"], authorable_xblock_names)

        # Note that "survey" is disabled in XBlockConfiguration, but it is still returned by
        # authorable_xblocks because it is marked as enabled and unsupported in XBlockStudioConfiguration.
        # Since XBlockConfiguration is a blacklist and relates to xblock type, while XBlockStudioConfiguration
        # is a whitelist and uses a combination of xblock type and template (and in addition has a global feature flag),
        # it is expected that Studio code will need to filter by both disabled_xblocks and authorable_xblocks.
        authorable_xblock_names = [block.name for block in authorable_xblocks(allow_unsupported=True)]
        self.assertCountEqual(
            ["survey", "done", "problem", "problem", "problem", "html", "split_module"],
            authorable_xblock_names
        )

    def test_authorable_blocks_by_name(self):
        """
        Tests authorable_xblocks when name is specified.
        """
        def verify_xblock_fields(name, template, support_level, block):
            """
            Verifies the returned xblock state.
            """
            assert name == block.name
            assert template == block.template
            assert support_level == block.support_level

        # There are no xblocks with name video.
        authorable_blocks = authorable_xblocks(name="video")
        assert 0 == len(authorable_blocks)

        # There is only a single html xblock.
        authorable_blocks = authorable_xblocks(name="html")
        assert 1 == len(authorable_blocks)
        verify_xblock_fields("html", "zoom", XBlockStudioConfiguration.PROVISIONAL_SUPPORT, authorable_blocks[0])

        authorable_blocks = authorable_xblocks(name="problem", allow_unsupported=True)
        assert 3 == len(authorable_blocks)
        no_template = None
        circuit = None
        multiple_choice = None
        for block in authorable_blocks:
            if block.template == '':
                no_template = block
            elif block.template == 'circuit_schematic_builder':
                circuit = block
            elif block.template == 'multiple_choice':
                multiple_choice = block

        verify_xblock_fields("problem", "", XBlockStudioConfiguration.FULL_SUPPORT, no_template)
        verify_xblock_fields("problem", "circuit_schematic_builder", XBlockStudioConfiguration.UNSUPPORTED, circuit)
        verify_xblock_fields("problem", "multiple_choice", XBlockStudioConfiguration.FULL_SUPPORT, multiple_choice)

"""
Tests related to XBlock support API.
"""
from openedx.core.djangolib.testing.utils import CacheIsolationTestCase
from common.djangoapps.xblock_django.api import authorable_xblocks, deprecated_xblocks, disabled_xblocks
from common.djangoapps.xblock_django.models import XBlockConfiguration, XBlockStudioConfiguration, XBlockStudioConfigurationFlag  # lint-amnesty, pylint: disable=line-too-long


class XBlockSupportTestCase(CacheIsolationTestCase):
    """
    Tests for XBlock Support methods.
    """
    def setUp(self):
        super().setUp()

        # Set up XBlockConfigurations for disabled and deprecated states
        block_config = [
            ("poll", True, True),
            ("survey", False, True),
            ("done", True, False),
        ]

        for name, enabled, deprecated in block_config:
            XBlockConfiguration(name=name, enabled=enabled, deprecated=deprecated).save()

        # Set up XBlockStudioConfigurations for studio support level
        studio_block_config = [
            ("poll", "", False, XBlockStudioConfiguration.FULL_SUPPORT),  # FULL_SUPPORT negated by enabled=False
            ("survey", "", True, XBlockStudioConfiguration.UNSUPPORTED),
            ("done", "", True, XBlockStudioConfiguration.FULL_SUPPORT),
            ("problem", "", True, XBlockStudioConfiguration.FULL_SUPPORT),
            ("problem", "multiple_choice", True, XBlockStudioConfiguration.FULL_SUPPORT),
            ("problem", "circuit_schematic_builder", True, XBlockStudioConfiguration.UNSUPPORTED),
            ("problem", "ora1", False, XBlockStudioConfiguration.FULL_SUPPORT),
            ("html", "zoom", True, XBlockStudioConfiguration.PROVISIONAL_SUPPORT),
            ("split_module", "", True, XBlockStudioConfiguration.UNSUPPORTED),
        ]

        for name, template, enabled, support_level in studio_block_config:
            XBlockStudioConfiguration(name=name, template=template, enabled=enabled, support_level=support_level).save()

    def test_deprecated_blocks(self):
        """ Tests the deprecated_xblocks method """

        deprecated_xblock_names = [block.name for block in deprecated_xblocks()]
        self.assertCountEqual(["poll", "survey"], deprecated_xblock_names)

        XBlockConfiguration(name="poll", enabled=True, deprecated=False).save()

        deprecated_xblock_names = [block.name for block in deprecated_xblocks()]
        self.assertCountEqual(["survey"], deprecated_xblock_names)

    def test_disabled_blocks(self):
        """ Tests the disabled_xblocks method """

        disabled_xblock_names = [block.name for block in disabled_xblocks()]
        self.assertCountEqual(["survey"], disabled_xblock_names)

        XBlockConfiguration(name="poll", enabled=False, deprecated=True).save()

        disabled_xblock_names = [block.name for block in disabled_xblocks()]
        self.assertCountEqual(["survey", "poll"], disabled_xblock_names)

    def test_authorable_blocks_empty_model(self):
        """
        Tests authorable_xblocks returns an empty list if XBlockStudioConfiguration table is empty, regardless
        of whether or not XBlockStudioConfigurationFlag is enabled.
        """
        XBlockStudioConfiguration.objects.all().delete()
        assert not XBlockStudioConfigurationFlag.is_enabled()
        assert 0 == len(authorable_xblocks(allow_unsupported=True))
        XBlockStudioConfigurationFlag(enabled=True).save()
        assert 0 == len(authorable_xblocks(allow_unsupported=True))

    def test_authorable_blocks(self):
        """
        Tests authorable_xblocks when name is not specified.
        """
        authorable_xblock_names = [block.name for block in authorable_xblocks()]
        self.assertCountEqual(["done", "problem", "problem", "html"], authorable_xblock_names)

        # Note that "survey" is disabled in XBlockConfiguration, but it is still returned by
        # authorable_xblocks because it is marked as enabled and unsupported in XBlockStudioConfiguration.
        # Since XBlockConfiguration is a blacklist and relates to xblock type, while XBlockStudioConfiguration
        # is a whitelist and uses a combination of xblock type and template (and in addition has a global feature flag),
        # it is expected that Studio code will need to filter by both disabled_xblocks and authorable_xblocks.
        authorable_xblock_names = [block.name for block in authorable_xblocks(allow_unsupported=True)]
        self.assertCountEqual(
            ["survey", "done", "problem", "problem", "problem", "html", "split_module"],
            authorable_xblock_names
        )

    def test_authorable_blocks_by_name(self):
        """
        Tests authorable_xblocks when name is specified.
        """
        def verify_xblock_fields(name, template, support_level, block):
            """
            Verifies the returned xblock state.
            """
            assert name == block.name
            assert template == block.template
            assert support_level == block.support_level

        # There are no xblocks with name video.
        authorable_blocks = authorable_xblocks(name="video")
        assert 0 == len(authorable_blocks)

        # There is only a single html xblock.
        authorable_blocks = authorable_xblocks(name="html")
        assert 1 == len(authorable_blocks)
        verify_xblock_fields("html", "zoom", XBlockStudioConfiguration.PROVISIONAL_SUPPORT, authorable_blocks[0])

        authorable_blocks = authorable_xblocks(name="problem", allow_unsupported=True)
        assert 3 == len(authorable_blocks)
        no_template = None
        circuit = None
        multiple_choice = None
        for block in authorable_blocks:
            if block.template == '':
                no_template = block
            elif block.template == 'circuit_schematic_builder':
                circuit = block
            elif block.template == 'multiple_choice':
                multiple_choice = block

        verify_xblock_fields("problem", "", XBlockStudioConfiguration.FULL_SUPPORT, no_template)
        verify_xblock_fields("problem", "circuit_schematic_builder", XBlockStudioConfiguration.UNSUPPORTED, circuit)
        verify_xblock_fields("problem", "multiple_choice", XBlockStudioConfiguration.FULL_SUPPORT, multiple_choice)

Tests related to XBlock support API. # lint-amnesty, pylint: disable=line-too-long Tests for XBlock Support methods. # Set up XBlockConfigurations for disabled and deprecated states # Set up XBlockStudioConfigurations for studio support level # FULL_SUPPORT negated by enabled=False Tests the deprecated_xblocks method Tests the disabled_xblocks method Tests authorable_xblocks returns an empty list if XBlockStudioConfiguration table is empty, regardless         of whether or not XBlockStudioConfigurationFlag is enabled. Tests authorable_xblocks when name is not specified. # Note that "survey" is disabled in XBlockConfiguration, but it is still returned by # authorable_xblocks because it is marked as enabled and unsupported in XBlockStudioConfiguration. # Since XBlockConfiguration is a blacklist and relates to xblock type, while XBlockStudioConfiguration # is a whitelist and uses a combination of xblock type and template (and in addition has a global feature flag), # it is expected that Studio code will need to filter by both disabled_xblocks and authorable_xblocks. Tests authorable_xblocks when name is specified. Verifies the returned xblock state. # There are no xblocks with name video. # There is only a single html xblock.