Python django.utils.http.urlquote() Examples

The following are 30 code examples of django.utils.http.urlquote(). You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may also want to check out all available functions/classes of the module django.utils.http , or try the search function .
Example #1
Source File: test_admin_views.py    From wagtail with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
def test_get(self):
        """
        This tests that the view responds correctly for a user with edit permissions on this image
        """
        # Get
        response = self.client.get(reverse('wagtailimages:generate_url', args=(self.image.id, 'fill-800x600')))

        # Check response
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response['Content-Type'], 'application/json')

        # Check JSON
        content_json = json.loads(response.content.decode())

        self.assertEqual(set(content_json.keys()), set(['url', 'preview_url']))

        expected_url = 'http://localhost/images/%(signature)s/%(image_id)d/fill-800x600/' % {
            'signature': urlquote(generate_signature(self.image.id, 'fill-800x600'), safe=urlquote_safechars),
            'image_id': self.image.id,
        }
        self.assertEqual(content_json['url'], expected_url)

        expected_preview_url = reverse('wagtailimages:preview', args=(self.image.id, 'fill-800x600'))
        self.assertEqual(content_json['preview_url'], expected_preview_url) 
Example #2
Source File: __init__.py    From Inboxen with GNU Affero General Public License v3.0 6 votes vote down vote up
def proxy_url(url):
    url_parts = url.split(":")
    if len(url_parts) > 1:
        # check to see if the second item is a port number
        try:
            port = int(url_parts[1], 10)
        except ValueError:
            # second part of url was not a port
            port = 0

        # if the second part of a url is not a port, then we can assume the
        # first must be a protocol scheme
        if port == 0 and url_parts[0] not in ALLOW_URL_SCHEMES:
            # url starts with a protocol, but it's not one that we can redirect
            # to safely
            return url

    proxy = reverse("redirect")
    url = urlquote(url)
    return "{proxy}?url={url}".format(proxy=proxy, url=url) 
Example #3
Source File: test_container_page.py    From ANALYSE with GNU Affero General Public License v3.0 6 votes vote down vote up
def test_container_html(self):
        self._test_html_content(
            self.child_container,
            expected_section_tag=(
                '<section class="wrapper-xblock level-page is-hidden studio-xblock-wrapper" '
                'data-locator="{0}" data-course-key="{0.course_key}">'.format(self.child_container.location)
            ),
            expected_breadcrumbs=(
                r'<a href="/course/{course}{section_parameters}" class="{classes}">\s*Week 1\s*</a>\s*'
                r'<a href="/course/{course}{subsection_parameters}" class="{classes}">\s*Lesson 1\s*</a>\s*'
                r'<a href="/container/{unit}" class="{classes}">\s*Unit\s*</a>'
            ).format(
                course=re.escape(unicode(self.course.id)),
                unit=re.escape(unicode(self.vertical.location)),
                classes='navigation-item navigation-link navigation-parent',
                section_parameters=re.escape(u'?show={}'.format(http.urlquote(self.chapter.location))),
                subsection_parameters=re.escape(u'?show={}'.format(http.urlquote(self.sequential.location))),
            ),
        ) 
Example #4
Source File: views.py    From SchoolIdolAPI with Apache License 2.0 6 votes vote down vote up
def create(request):
    if request.user.is_authenticated() and not request.user.is_anonymous():
        return redirect('/user/' + request.user.username + '/')
    if request.method == "POST":
        form = forms.CreateUserForm(request.POST)
        if form.is_valid():
            new_user = User.objects.create_user(**form.cleaned_data)
            user = authenticate(username=form.cleaned_data['username'], password=form.cleaned_data['password'])
            preferences = models.UserPreferences.objects.create(user=user)
            login(request, user)
            return redirect('/addaccount/' + ('?next=' + urlquote(request.GET['next']) if 'next' in request.GET else ''))
    else:
        form = forms.CreateUserForm()
    context = globalContext(request)
    context['form'] = form
    context['current'] = 'create'
    context['next'] = request.GET.get('next', None)
    return render(request, 'create.html', context) 
Example #5
Source File: cache.py    From luscan-devel with GNU General Public License v2.0 6 votes vote down vote up
def render(self, context):
        try:
            expire_time = self.expire_time_var.resolve(context)
        except VariableDoesNotExist:
            raise TemplateSyntaxError('"cache" tag got an unknown variable: %r' % self.expire_time_var.var)
        try:
            expire_time = int(expire_time)
        except (ValueError, TypeError):
            raise TemplateSyntaxError('"cache" tag got a non-integer timeout value: %r' % expire_time)
        # Build a key for this fragment and all vary-on's.
        key = ':'.join([urlquote(resolve_variable(var, context)) for var in self.vary_on])
        args = hashlib.md5(force_bytes(key))
        cache_key = 'template.cache.%s.%s' % (self.fragment_name, args.hexdigest())
        value = cache.get(cache_key)
        if value is None:
            value = self.nodelist.render(context)
            cache.set(cache_key, value, expire_time)
        return value 
Example #6
Source File: views.py    From SchoolIdolAPI with Apache License 2.0 6 votes vote down vote up
def addaccount(request):
    if not request.user.is_authenticated() or request.user.is_anonymous():
        raise PermissionDenied()
    if request.method == "POST":
        form = forms.AccountForm(request.POST)
        if form.is_valid():
            account = form.save(commit=False)
            next_url = lambda account: '/cards/initialsetup/?account=' + str(account.id) + ('&starter=' + str(account.center_id) if account.center_id else '&starter=0') + ('&next=' + urlquote(request.GET['next']) if 'next' in request.GET else '')
            account.owner = request.user
            if account.rank >= 200:
                account.rank = 195
                account.save()
                _addaccount_savecenter(account)
                return redirect(next_url(account) + '&notification=ADDACCOUNTRANK200&notification_link_variables=' + str(account.pk))
            account.save()
            _addaccount_savecenter(account)
            return redirect(next_url(account))
    else:
        form = forms.AccountForm(initial={
            'nickname': request.user.username
        })
    context = globalContext(request)
    context['form'] = form
    context['current'] = 'addaccount'
    return render(request, 'addaccount.html', context) 
Example #7
Source File: middleware.py    From online-judge with GNU Affero General Public License v3.0 6 votes vote down vote up
def __call__(self, request):
        if request.user.is_authenticated:
            profile = request.profile = request.user.profile
            logout_path = reverse('auth_logout')
            login_2fa_path = reverse('login_2fa')
            webauthn_path = reverse('webauthn_assert')
            change_password_path = reverse('password_change')
            change_password_done_path = reverse('password_change_done')
            has_2fa = profile.is_totp_enabled or profile.is_webauthn_enabled
            if (has_2fa and not request.session.get('2fa_passed', False) and
                    request.path not in (login_2fa_path, logout_path, webauthn_path) and
                    not request.path.startswith(settings.STATIC_URL)):
                return HttpResponseRedirect(login_2fa_path + '?next=' + urlquote(request.get_full_path()))
            elif (request.session.get('password_pwned', False) and
                    request.path not in (change_password_path, change_password_done_path,
                                         login_2fa_path, logout_path) and
                    not request.path.startswith(settings.STATIC_URL)):
                return HttpResponseRedirect(change_password_path + '?next=' + urlquote(request.get_full_path()))
        else:
            request.profile = None
        return self.get_response(request) 
Example #8
Source File: rendering.py    From django-easy-pdf with MIT License 6 votes vote down vote up
def encode_filename(filename):
    """
    Encodes filename part for ``Content-Disposition: attachment``.

    >>> print(encode_filename("abc.pdf"))
    filename=abc.pdf
    >>> print(encode_filename("aa bb.pdf"))
    filename*=UTF-8''aa%20bb.pdf
    >>> print(encode_filename(u"zażółć.pdf"))
    filename*=UTF-8''za%C5%BC%C3%B3%C5%82%C4%87.pdf
    """
    # TODO: http://greenbytes.de/tech/webdav/rfc6266.html
    # TODO: http://greenbytes.de/tech/tc2231/

    quoted = urlquote(filename)
    if quoted == filename:
        return "filename=%s" % filename
    else:
        return "filename*=UTF-8''%s" % quoted 
Example #9
Source File: test_engagement_timelines.py    From edx-analytics-data-api with GNU Affero General Public License v3.0 5 votes vote down vote up
def test_not_found(self, course_id):
        path = self.path_template.format(self.DEFAULT_USERNAME, urlquote(course_id))
        response = self.authenticated_get(path)
        self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
        expected = {
            u"error_code": u"no_learner_engagement_timeline",
            u"developer_message": u"Learner {} engagement timeline not found for course {}.".format(
                self.DEFAULT_USERNAME, course_id)
        }
        self.assertDictEqual(json.loads(response.content.decode('utf-8')), expected) 
Example #10
Source File: dashboard.py    From ImitationTmall_Django with GNU General Public License v3.0 5 votes vote down vote up
def get_context(self):
        new_context = {
            'title': self.get_title(),
            'icon': self.icon,
            'portal_key': self.get_portal_key(),
            'columns': [('col-sm-%d' % int(12 / len(self.widgets)), ws) for ws in self.widgets],
            'has_add_widget_permission': self.has_model_perm(UserWidget, 'add') and self.widget_customiz,
            'add_widget_url': self.get_admin_url('%s_%s_add' % (UserWidget._meta.app_label, UserWidget._meta.model_name)) +
            "?user=%s&page_id=%s&_redirect=%s" % (self.user.id, self.get_page_id(), urlquote(self.request.get_full_path()))
        }
        context = super(Dashboard, self).get_context()
        context.update(new_context)
        return context 
Example #11
Source File: tables.py    From avos with Apache License 2.0 5 votes vote down vote up
def get_vip_link(pool):
    if pool.vip_id:
        return reverse("horizon:project:loadbalancers:vipdetails",
                       args=(http.urlquote(pool.vip_id),))
    else:
        return None 
Example #12
Source File: models.py    From wagtailnews with BSD 2-Clause "Simplified" License 5 votes vote down vote up
def v_post(self, request, year, month, day, pk, slug):
        newsitem = get_object_or_404(self.get_newsitems_for_display(), pk=pk)

        # Check the URL date and slug are still correct
        newsitem_url = newsitem.url
        newsitem_path = urlparse(newsitem_url, allow_fragments=True).path
        if urlquote(request.path) != newsitem_path:
            return HttpResponsePermanentRedirect(newsitem_url)

        # Get the newsitem to serve itself
        return newsitem.serve(request) 
Example #13
Source File: tables.py    From avos with Apache License 2.0 5 votes vote down vote up
def get_cluster_link(job_execution):
    return reverse("horizon:project:data_processing.clusters:details",
                   args=(http.urlquote(job_execution.cluster_id),)) 
Example #14
Source File: test_engagement_timelines.py    From edx-analytics-data-api with GNU Affero General Public License v3.0 5 votes vote down vote up
def test_metric_aggregation(self, course_id, entity_type, event_type, metric_display_name, expect_id_aggregation):
        """
        Verify that some metrics are counted by unique ID, while some are
        counted by total interactions.
        """
        create_engagement(course_id, self.DEFAULT_USERNAME, entity_type, event_type, 'entity-id', 5)
        create_engagement(course_id, self.DEFAULT_USERNAME, entity_type, event_type, 'entity-id', 5)
        expected_data = {
            'days': [
                {
                    'date': '2015-01-01',
                    'discussion_contributions': 0,
                    'problems_attempted': 0,
                    'problems_completed': 0,
                    'videos_viewed': 0,
                }
            ]
        }
        if expect_id_aggregation:
            expected_data['days'][0][metric_display_name] = 1
        else:
            expected_data['days'][0][metric_display_name] = 10
        path = self.path_template.format(self.DEFAULT_USERNAME, urlquote(course_id))
        response = self.authenticated_get(path)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(
            response.data,
            expected_data
        ) 
Example #15
Source File: test_engagement_timelines.py    From edx-analytics-data-api with GNU Affero General Public License v3.0 5 votes vote down vote up
def test_timeline(self, course_id):
        """
        Smoke test the learner engagement timeline.
        """
        path = self.path_template.format(self.DEFAULT_USERNAME, urlquote(course_id))
        day_one = datetime.datetime(2015, 1, 1, tzinfo=pytz.utc)
        day_two = datetime.datetime(2015, 1, 2, tzinfo=pytz.utc)
        create_engagement(course_id, self.DEFAULT_USERNAME, PROBLEM, ATTEMPTED, 'id-1', count=100, date=day_one)
        create_engagement(course_id, self.DEFAULT_USERNAME, PROBLEM, COMPLETED, 'id-2', count=12, date=day_one)
        create_engagement(course_id, self.DEFAULT_USERNAME, DISCUSSION, CONTRIBUTED, 'id-3', count=6, date=day_one)
        create_engagement(course_id, self.DEFAULT_USERNAME, DISCUSSION, CONTRIBUTED, 'id-4', count=10, date=day_two)
        create_engagement(course_id, self.DEFAULT_USERNAME, VIDEO, VIEWED, 'id-5', count=44, date=day_two)
        create_engagement(course_id, self.DEFAULT_USERNAME, PROBLEM, ATTEMPTED, 'id-6', count=8, date=day_two)
        create_engagement(course_id, self.DEFAULT_USERNAME, PROBLEM, ATTEMPTED, 'id-7', count=4, date=day_two)
        response = self.authenticated_get(path)
        self.assertEqual(response.status_code, 200)
        expected = {
            'days': [
                {
                    'date': '2015-01-01',
                    'discussion_contributions': 6,
                    'problems_attempted': 1,
                    'problems_completed': 1,
                    'videos_viewed': 0
                },
                {
                    'date': '2015-01-02',
                    'discussion_contributions': 10,
                    'problems_attempted': 2,
                    'problems_completed': 0,
                    'videos_viewed': 1
                },
            ]
        }
        self.assertEqual(response.data, expected) 
Example #16
Source File: test_engagement_timelines.py    From edx-analytics-data-api with GNU Affero General Public License v3.0 5 votes vote down vote up
def test_day_gap(self, course_id):
        path = self.path_template.format(self.DEFAULT_USERNAME, urlquote(course_id))
        first_day = datetime.datetime(2015, 5, 26, tzinfo=pytz.utc)
        last_day = datetime.datetime(2015, 5, 28, tzinfo=pytz.utc)
        create_engagement(course_id, self.DEFAULT_USERNAME, VIDEO, VIEWED, 'id-1', 1, date=first_day)
        create_engagement(course_id, self.DEFAULT_USERNAME, PROBLEM, ATTEMPTED, 'id-2', 1, date=last_day)
        response = self.authenticated_get(path)
        self.assertEqual(response.status_code, 200)
        expected = {
            'days': [
                {
                    'date': '2015-05-26',
                    'discussion_contributions': 0,
                    'problems_attempted': 0,
                    'problems_completed': 0,
                    'videos_viewed': 1
                },
                {
                    'date': '2015-05-27',
                    'discussion_contributions': 0,
                    'problems_attempted': 0,
                    'problems_completed': 0,
                    'videos_viewed': 0
                },
                {
                    'date': '2015-05-28',
                    'discussion_contributions': 0,
                    'problems_attempted': 1,
                    'problems_completed': 0,
                    'videos_viewed': 0
                },
            ]
        }
        self.assertEqual(response.data, expected) 
Example #17
Source File: models.py    From pdpdmeetup with MIT License 5 votes vote down vote up
def get_absolute_url(self):
        return "/users/%s/" % urlquote(self.email) 
Example #18
Source File: utils.py    From steemprojects.com with MIT License 5 votes vote down vote up
def make_template_fragment_key(fragment_name, vary_on=None):
    if vary_on is None:
        vary_on = ()
    key = ':'.join([urlquote(var) for var in vary_on])
    args = hashlib.md5(key.encode('utf-8'))
    return TEMPLATE_FRAGMENT_KEY_TEMPLATE % (fragment_name, args.hexdigest()) 
Example #19
Source File: dashboard.py    From Dailyfresh-B2C with Apache License 2.0 5 votes vote down vote up
def get_context(self):
        new_context = {
            'title': self.get_title(),
            'icon': self.icon,
            'portal_key': self.get_portal_key(),
            'columns': [('col-sm-%d' % int(12 / len(self.widgets)), ws) for ws in self.widgets],
            'has_add_widget_permission': self.has_model_perm(UserWidget, 'add') and self.widget_customiz,
            'add_widget_url': self.get_admin_url('%s_%s_add' % (UserWidget._meta.app_label, UserWidget._meta.model_name)) +
            "?user=%s&page_id=%s&_redirect=%s" % (self.user.id, self.get_page_id(), urlquote(self.request.get_full_path()))
        }
        context = super(Dashboard, self).get_context()
        context.update(new_context)
        return context 
Example #20
Source File: defaultfilters.py    From openhgsenti with Apache License 2.0 5 votes vote down vote up
def urlencode(value, safe=None):
    """
    Escapes a value for use in a URL.

    Takes an optional ``safe`` parameter used to determine the characters which
    should not be escaped by Django's ``urlquote`` method. If not provided, the
    default safe characters will be used (but an empty string can be provided
    when *all* characters should be escaped).
    """
    kwargs = {}
    if safe is not None:
        kwargs['safe'] = safe
    return urlquote(value, **kwargs) 
Example #21
Source File: dashboard.py    From online with GNU Affero General Public License v3.0 5 votes vote down vote up
def get_context(self):
        new_context = {
            'title': self.get_title(),
            'icon': self.icon,
            'portal_key': self.get_portal_key(),
            'columns': [('col-sm-%d' % int(12 / len(self.widgets)), ws) for ws in self.widgets],
            'has_add_widget_permission': self.has_model_perm(UserWidget, 'add') and self.widget_customiz,
            'add_widget_url': self.get_admin_url('%s_%s_add' % (UserWidget._meta.app_label, UserWidget._meta.model_name)) +
            "?user=%s&page_id=%s&_redirect=%s" % (self.user.id, self.get_page_id(), urlquote(self.request.get_full_path()))
        }
        context = super(Dashboard, self).get_context()
        context.update(new_context)
        return context 
Example #22
Source File: dashboard.py    From devops with MIT License 5 votes vote down vote up
def get_context(self):
        new_context = {
            'title': self.get_title(),
            'icon': self.icon,
            'portal_key': self.get_portal_key(),
            'columns': [('col-sm-%d' % int(12 / len(self.widgets)), ws) for ws in self.widgets],
            'has_add_widget_permission': self.has_model_perm(UserWidget, 'add') and self.widget_customiz,
            'add_widget_url': self.get_admin_url('%s_%s_add' % (UserWidget._meta.app_label, UserWidget._meta.model_name)) +
            "?user=%s&page_id=%s&_redirect=%s" % (self.user.id, self.get_page_id(), urlquote(self.request.get_full_path()))
        }
        context = super(Dashboard, self).get_context()
        context.update(new_context)
        return context 
Example #23
Source File: dashboard.py    From imoocc with GNU General Public License v2.0 5 votes vote down vote up
def get_context(self):
        new_context = {
            'title': self.get_title(),
            'icon': self.icon,
            'portal_key': self.get_portal_key(),
            'columns': [('col-sm-%d' % int(12 / len(self.widgets)), ws) for ws in self.widgets],
            'has_add_widget_permission': self.has_model_perm(UserWidget, 'add') and self.widget_customiz,
            'add_widget_url': self.get_admin_url('%s_%s_add' % (UserWidget._meta.app_label, UserWidget._meta.model_name)) +
            "?user=%s&page_id=%s&_redirect=%s" % (self.user.id, self.get_page_id(), urlquote(self.request.get_full_path()))
        }
        context = super(Dashboard, self).get_context()
        context.update(new_context)
        return context 
Example #24
Source File: defaultfilters.py    From python2017 with MIT License 5 votes vote down vote up
def urlencode(value, safe=None):
    """
    Escapes a value for use in a URL.

    Takes an optional ``safe`` parameter used to determine the characters which
    should not be escaped by Django's ``urlquote`` method. If not provided, the
    default safe characters will be used (but an empty string can be provided
    when *all* characters should be escaped).
    """
    kwargs = {}
    if safe is not None:
        kwargs['safe'] = safe
    return urlquote(value, **kwargs) 
Example #25
Source File: test_views.py    From edx-analytics-dashboard with GNU Affero General Public License v3.0 5 votes vote down vote up
def assertRedirectsNoFollow(self, response, expected_url, status_code=302, **querystringkwargs):
        if querystringkwargs:
            expected_url += '?{}'.format('&'.join('%s=%s' % (key, urlquote(value))
                                                  for (key, value) in querystringkwargs.items()))

        self.assertEqual(response['Location'], '{}'.format(expected_url))
        self.assertEqual(response.status_code, status_code) 
Example #26
Source File: dashboard.py    From Mxonline3 with Apache License 2.0 5 votes vote down vote up
def get_context(self):
        new_context = {
            'title': self.get_title(),
            'icon': self.icon,
            'portal_key': self.get_portal_key(),
            'columns': [('col-sm-%d' % int(12 / len(self.widgets)), ws) for ws in self.widgets],
            'has_add_widget_permission': self.has_model_perm(UserWidget, 'add') and self.widget_customiz,
            'add_widget_url': self.get_admin_url('%s_%s_add' % (UserWidget._meta.app_label, UserWidget._meta.model_name)) +
            "?user=%s&page_id=%s&_redirect=%s" % (self.user.id, self.get_page_id(), urlquote(self.request.get_full_path()))
        }
        context = super(Dashboard, self).get_context()
        context.update(new_context)
        return context 
Example #27
Source File: htmltemplating.py    From open-context-py with GNU General Public License v3.0 5 votes vote down vote up
def make_cors_ok_url(self, url):
        """ checks to see if the url is on the CORS ok
            list. If not, make a proxy URL
        """
        make_proxy = True  # default to making a proxy
        for cors_ok_domain in settings.CORS_OK_DOMAINS:
            if cors_ok_domain in url:
                make_proxy = False
                break
        if make_proxy:
            rp = RootPath()
            url = rp.get_baseurl() + '/entities/proxy/' + urlquote(url)
        return url 
Example #28
Source File: templating.py    From open-context-py with GNU General Public License v3.0 5 votes vote down vote up
def make_cors_ok_url(self, url):
        """ checks to see if the url is on the CORS ok
            list. If not, make a proxy URL
        """
        make_proxy = True  # default to making a proxy
        for cors_ok_domain in settings.CORS_OK_DOMAINS:
            if cors_ok_domain in url:
                make_proxy = False
                break
        if make_proxy:
            rp = RootPath()
            url = rp.get_baseurl() + '/entities/proxy/' + urlquote(url)
        return url 
Example #29
Source File: merritt.py    From open-context-py with GNU General Public License v3.0 5 votes vote down vote up
def update_item_media_files(self, ark_id, uuid):
        """ updates media files associated with an item
        """
        old_files = Mediafile.objects.filter(uuid=uuid)
        for old_file in old_files:
            media_files = None
            if self.BASE_MERRITT not in old_file.file_uri:
                # the file_uri is not in Merritt, so do update
                # processes
                if media_files is None:
                    # a file_uri is not in Merritt, so go to
                    # Merritt and get the files for this item
                    media_files = self.get_item_media_files(ark_id,
                                                            uuid)
                if isinstance(media_files, list):
                    # we have a list of media files from Merritt
                    # so now check to update 
                    if old_file.file_type in self.FILE_TYPE_MAPPINGS:
                        type_pattern = urlquote(self.FILE_TYPE_MAPPINGS[old_file.file_type],
                                                safe='')
                        found_file = False
                        for media_file in media_files:
                            if type_pattern in media_file:
                                found_file = media_file
                                break
                        if found_file is not False:
                            if uuid not in self.updated_uuids:
                                self.updated_uuids.append(uuid)
                            self.updated_file_count += 1
                            old_file.file_uri = found_file
                            old_file.save()
                            output = '\n\n'
                            output += 'Saved file: ' + str(self.updated_file_count)
                            output += ' of uuid: ' + str(len(self.updated_uuids))
                            output += '\n'
                            output += found_file
                            print(output) 
Example #30
Source File: test_container_page.py    From ANALYSE with GNU Affero General Public License v3.0 5 votes vote down vote up
def test_container_on_container_html(self):
        """
        Create the scenario of an xblock with children (non-vertical) on the container page.
        This should create a container page that is a child of another container page.
        """
        draft_container = self._create_item(self.child_container.location, "wrapper", "Wrapper")
        self._create_item(draft_container.location, "html", "Child HTML")

        def test_container_html(xblock):
            self._test_html_content(
                xblock,
                expected_section_tag=(
                    '<section class="wrapper-xblock level-page is-hidden studio-xblock-wrapper" '
                    'data-locator="{0}" data-course-key="{0.course_key}">'.format(draft_container.location)
                ),
                expected_breadcrumbs=(
                    r'<a href="/course/{course}{section_parameters}" class="{classes}">\s*Week 1\s*</a>\s*'
                    r'<a href="/course/{course}{subsection_parameters}" class="{classes}">\s*Lesson 1\s*</a>\s*'
                    r'<a href="/container/{unit}" class="{classes}">\s*Unit\s*</a>\s*'
                    r'<a href="/container/{split_test}" class="{classes}">\s*Split Test\s*</a>'
                ).format(
                    course=re.escape(unicode(self.course.id)),
                    unit=re.escape(unicode(self.vertical.location)),
                    split_test=re.escape(unicode(self.child_container.location)),
                    classes='navigation-item navigation-link navigation-parent',
                    section_parameters=re.escape(u'?show={}'.format(http.urlquote(self.chapter.location))),
                    subsection_parameters=re.escape(u'?show={}'.format(http.urlquote(self.sequential.location))),
                ),
            )

        # Test the draft version of the container
        test_container_html(draft_container)

        # Now publish the unit and validate again
        self.store.publish(self.vertical.location, self.user.id)
        draft_container = self.store.get_item(draft_container.location)
        test_container_html(draft_container)