"""This module holds the tests of the ``qrcodes`` app."""

import qrcode.image.pil

from mtp.apps.common.tests.test_cases import MTPTestCase

from .qrcode import QRCode, ObjectQRCode


class QRCodeTestCase(MTPTestCase):
    """Test case that tests the ``QRCode`` class."""

    def test_generate_qrcode(self):
        """Test that ``generate_qrcode`` method works."""

        data = {'foo': 'bar'}
        generated_qrcode = QRCode(data).generate()
        self.assertTrue(isinstance(generated_qrcode, qrcode.image.pil.PilImage))

    def test_get_qrcode_context_data(self):
        """Test that ``_get_qrcode_context_data`` method works."""

        data = {'foo': 'bar'}
        qr_code = QRCode(data)
        self.assertEqual(qr_code._get_qrcode_context_data(), data)


class ObjectQRCodeTestCase(MTPTestCase):
    """Test case that tests the ``QRCode`` class."""

    class StringQRCode(ObjectQRCode):
        """Test class to test ``ObjectQRCode``.

        Notes
        -----
        This class allows to transform str to QRCode.

        """

        object_class = str

        def _get_qrcode_context_data(self, **kwargs):
            """Tests the get of QRCode context data.

            Notes
            -----
            We store in QRCode the upper and lower version of str object.

            """

            upper_value = self.get_object().upper()
            lower_value = self.get_object().lower()

            return super()._get_qrcode_context_data(
                upper_value=upper_value,
                lower_value=lower_value
            )

    def test_generate_qrcode(self):
        """Test that ``generate_qrcode`` method works."""

        # The provided object is a str object.
        generated_qrcode = self.StringQRCode('fake-test').generate()
        self.assertTrue(isinstance(generated_qrcode, qrcode.image.pil.PilImage))

    def test_get_qrcode_context_data(self):
        """Test that ``_get_qrcode_context_data`` method works."""

        qr_code = self.StringQRCode('fake-test')

        expected_data = {'upper_value': 'FAKE-TEST', 'lower_value': 'fake-test'}
        self.assertEqual(qr_code._get_qrcode_context_data(), expected_data)

        # We add optional data in QRCode initialization.
        qr_code = self.StringQRCode('fake-test', {'foo': 'bar'})

        expected_data = {'foo': 'bar', 'upper_value': 'FAKE-TEST', 'lower_value': 'fake-test'}
        self.assertEqual(qr_code._get_qrcode_context_data(), expected_data)
