def test_render_one_chunk(self):
        iframe = Iframe(region='test', content_id=1, content_type=self.ct,
                        url='https://news.bbc.co.uk/', position=1)
        iframe.full_clean()
        iframe.pk = 1

        request = RequestFactory().get('/')
        ctx = RequestContext(request)
        iterdata = chunk_iteration_context(
            index=0, value=iframe, iterable=[iframe])
        ctx.update(iterdata)
        output = render_one_chunk(context=ctx, chunk=iframe,
                                                extra=iterdata['chunkloop'],
                                                renderer=None).strip()
        self.assertIn('<iframe ', output)
        self.assertIn('src="https://news.bbc.co.uk/"', output)
        self.assertIn('data-position="1"', output)
        self.assertIn('data-pk="1"', output)
        self.assertIn('data-region="test"', output)
        self.assertIn('</iframe>', output)
    def get_subclass_summary(self, obj):
        """
        show a brief, HTML aware summary of the content.

        .. note::
            By using this callable, we avoid the problem of being able to
            sort by headers in the changelists (including on the change form)

        :return: short representation of the data, HTML included.
        :rtype: string
        """
        modeladmin = get_modeladmin(obj)
        if hasattr(modeladmin, 'get_editregions_subclass_summary'):
            value = modeladmin.get_editregions_subclass_summary(obj=obj)
        elif hasattr(modeladmin, 'render_into_summary'):
            context = chunk_iteration_context(index=0, value=obj,
                                               iterable=(obj,))
            context.update({'admin_summary': True})
            value = modeladmin.render_into_summary(obj=obj, context=context)
        else:
            value = '[missing]'
        value = strip_tags(force_text(value))
        return self.get_changelist_link_html(obj, data=value,
                                             caller='summary')
    def test_chunk_iteration_context(self):
        """
        Sample context:
        {'chunkloop': {'counter': 1,
               'counter0': 0,
               'first': True,
               'last': False,
               'next': 1,
               'next0': 0,
               'next_plugin': FakedChunk(region='test', position=2),
               'object': FakedChunk(region='test', position=1),
               'previous': None,
               'previous0': None,
               'previous_plugin': None,
               'region': 'test',
               'remaining_plugins': [FakedChunk(region='test', position=1),
                                     FakedChunk(region='test', position=2),
                                     FakedChunk(region='test', position=3),
                                     FakedChunk(region='test', position=4),
                                     FakedChunk(region='test', position=5),
                                     FakedChunk(region='test', position=6),
                                     FakedChunk(region='test', position=7),
                                     FakedChunk(region='test', position=8),
                                     FakedChunk(region='test', position=9)],
               'revcounter': 10,
               'revcounter0': 9,
               'total': 10,
               'used_plugins': []}}
        """
        FakeChunk = namedtuple('FakedChunk', ['region', 'position'])

        iterable = [FakeChunk(region='test', position=x) for x in range(0, 10)]
        first = iterable[0]
        last = iterable[-1]
        for offset, obj in enumerate(iterable):
            ctx = chunk_iteration_context(index=offset, value=obj,
                                                        iterable=iterable)
            self.assertEqual(ctx['chunkloop'].counter, offset+1)
            self.assertEqual(ctx['chunkloop'].counter0, offset)

            if obj == last:
                self.assertEqual(ctx['chunkloop'].next, None)
                self.assertEqual(ctx['chunkloop'].next0, None)
            else:
                self.assertEqual(ctx['chunkloop'].next, offset+1)
                self.assertEqual(ctx['chunkloop'].next0, offset)

            if obj == first:
                self.assertEqual(ctx['chunkloop'].previous, None)
                self.assertEqual(ctx['chunkloop'].previous0, None)
            else:
                self.assertEqual(ctx['chunkloop'].previous, offset)
                self.assertEqual(ctx['chunkloop'].previous0, offset - 1)

            self.assertEqual(ctx['chunkloop'].region, 'test')
            self.assertEqual(ctx['chunkloop'].revcounter,
                             len(iterable) - offset)
            self.assertEqual(ctx['chunkloop'].revcounter0,
                             len(iterable) - (offset+1))
            self.assertEqual(ctx['chunkloop'].total, len(iterable))

            # check the keys which track the loop history and future
            self.assertEqual(len(ctx['chunkloop'].used), offset)
            self.assertEqual(ctx['chunkloop'].used, iterable[0:offset])
            self.assertEqual(len(ctx['chunkloop'].remaining),
                             len(iterable) - (offset+1))
            self.assertEqual(ctx['chunkloop'].remaining, iterable[offset+1:])