class HashUrlEncodedExceptionFormatterTests(FantasticoUnitTestsCase):
    '''This class provides tests suite for HashUrlEncodedExceptionFormatter class.'''

    _formatter = None

    def init(self):
        '''This method is invoked automatically in order to set common dependencies for all test cases.'''

        self._formatter = HashUrlEncodedExceptionFormatter()

    def test_format_ex_ok(self):
        '''This test case ensures the correct string is returned when redirect uri does not have query parameters or
        hash section.'''

        ex_desc = {"attr2": "value", "attr1": "sample cool"}
        ctx = {"redirect_uri": "/example/cb"}

        expected_url = "/example/cb#attr1=%s&attr2=%s" % (urllib.parse.quote(
            ex_desc["attr1"]), ex_desc["attr2"])

        self.assertEqual(expected_url, self._formatter.format_ex(ex_desc, ctx))

    def test_format_ex_redirectwithhash_ok(self):
        '''This test case ensures the correct string is returned when redirect uri already contains a hash fragment.'''

        ex_desc = {"attr2": "value", "attr1": "sample"}
        ctx = {"redirect_uri": "/example/cb#hashf"}

        expected_url = "/example/cb#hashf&attr1=sample&attr2=value"

        self.assertEqual(expected_url, self._formatter.format_ex(ex_desc, ctx))

    def test_format_ex_redirectqparams_ok(self):
        '''This test case ensures the correct string is returned when redirect uri already contains query parameters.'''

        ex_desc = {"attr2": "value", "attr1": "sample"}
        ctx = {"redirect_uri": "/example/cb?q1=search"}

        expected_url = "/example/cb?q1=search#attr1=sample&attr2=value"

        self.assertEqual(expected_url, self._formatter.format_ex(ex_desc, ctx))

    def test_format_ex_nodesc(self):
        '''This test case ensures no exception is raised even though exception descriptor is None.'''

        ctx = {"redirect_uri": "/example/cb?q1=search"}

        for ex_desc in [None, {}]:
            self.assertEqual(ctx["redirect_uri"],
                             self._formatter.format_ex(ex_desc, ctx))

    def test_format_ex_invalidctx(self):
        '''This test case ensures an exception is raised if no valid context is provided.'''

        for formatter_ctx in [None, {}, {"attr": "invalid"}]:
            with self.assertRaises(KeyError) as ctx:
                self._formatter.format_ex(None, formatter_ctx)

            self.assertTrue(str(ctx.exception).find("redirect_uri") > -1)
class HashUrlEncodedExceptionFormatterTests(FantasticoUnitTestsCase):
    """This class provides tests suite for HashUrlEncodedExceptionFormatter class."""

    _formatter = None

    def init(self):
        """This method is invoked automatically in order to set common dependencies for all test cases."""

        self._formatter = HashUrlEncodedExceptionFormatter()

    def test_format_ex_ok(self):
        """This test case ensures the correct string is returned when redirect uri does not have query parameters or
        hash section."""

        ex_desc = {"attr2": "value", "attr1": "sample cool"}
        ctx = {"redirect_uri": "/example/cb"}

        expected_url = "/example/cb#attr1=%s&attr2=%s" % (urllib.parse.quote(ex_desc["attr1"]), ex_desc["attr2"])

        self.assertEqual(expected_url, self._formatter.format_ex(ex_desc, ctx))

    def test_format_ex_redirectwithhash_ok(self):
        """This test case ensures the correct string is returned when redirect uri already contains a hash fragment."""

        ex_desc = {"attr2": "value", "attr1": "sample"}
        ctx = {"redirect_uri": "/example/cb#hashf"}

        expected_url = "/example/cb#hashf&attr1=sample&attr2=value"

        self.assertEqual(expected_url, self._formatter.format_ex(ex_desc, ctx))

    def test_format_ex_redirectqparams_ok(self):
        """This test case ensures the correct string is returned when redirect uri already contains query parameters."""

        ex_desc = {"attr2": "value", "attr1": "sample"}
        ctx = {"redirect_uri": "/example/cb?q1=search"}

        expected_url = "/example/cb?q1=search#attr1=sample&attr2=value"

        self.assertEqual(expected_url, self._formatter.format_ex(ex_desc, ctx))

    def test_format_ex_nodesc(self):
        """This test case ensures no exception is raised even though exception descriptor is None."""

        ctx = {"redirect_uri": "/example/cb?q1=search"}

        for ex_desc in [None, {}]:
            self.assertEqual(ctx["redirect_uri"], self._formatter.format_ex(ex_desc, ctx))

    def test_format_ex_invalidctx(self):
        """This test case ensures an exception is raised if no valid context is provided."""

        for formatter_ctx in [None, {}, {"attr": "invalid"}]:
            with self.assertRaises(KeyError) as ctx:
                self._formatter.format_ex(None, formatter_ctx)

            self.assertTrue(str(ctx.exception).find("redirect_uri") > -1)
    def init(self):
        '''This method is invoked automatically in order to set common dependencies for all test cases.'''

        self._formatter = HashUrlEncodedExceptionFormatter()
    def init(self):
        """This method is invoked automatically in order to set common dependencies for all test cases."""

        self._formatter = HashUrlEncodedExceptionFormatter()