Opened 6 years ago

Last modified 5 years ago

#29098 new New feature

Allow assertRedirects to handle regex matches. — at Initial Version

Reported by: Dan J Strohl Owned by: nobody
Component: Testing framework Version: 2.1
Severity: Normal Keywords: unittest redirect
Cc: Dan Davis Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

or, perhaps, allow it to use the patterns from the url's file. Either way, the issue is that I have a view that gets a request, looks at it, and redirects it to a url such as /labs/12345/running, or /labs/4567/start. this is a similar pattern to what is recommended and used in the admin, so I don't think I am doing something weird here, but I may not know what the redirect url will look like before I send the request (if I am sending something like /labs/new, and it returns /labs/12345 for example).

as a hack, I did this:

Code highlighting:

def fix_response_for_test(response, re_pattern, replace, count=0, flags=0):

    if hasattr(response, 'redirect_chain'):
        url, status_code = response.redirect_chain[-1]

        tmp_replaced = re.search(re_pattern, url, flags=flags)
        new_url = re.sub(re_pattern, replace, url, count=count, flags=flags)

        # print('redirect - new: %s' % new_url)

        response.redirect_chain[-1] = (new_url, status_code)

    else:
        # Not a followed redirect
        url = response.url
        scheme, netloc, path, query, fragment = urlsplit(url)

        # Prepend the request path to handle relative path redirects.
        if not path.startswith('/'):
            url = urljoin(response.request['PATH_INFO'], url)

        tmp_replaced = re.search(re_pattern, url, flags=flags)
        new_url = re.sub(re_pattern, replace, url, count=count, flags=flags)

        # print('no redirected - new: %s' % new_url)

        response['Location'] = new_url

    return tmp_replaced.group(0)

and is run like this:

Code highlighting:

      session_id = fix_response_for_test(response, UUID_REGEX, '<uuid>')

      redirect_url = '/lab/<uuid>/error/'

      with self.subTest('%s - response url' % name):
              self.assertRedirects(response, redirect_url, fetch_redirect_response=False, msg_prefix=tmp_msg)
      test_session = Sessions.objects.get(session_id=session_id)
      # do more testing on the session object to make sure it was created correctly.

The returning the pulled content is nice, but probably not required as I COULD simply build two tests, one to check the redirect, and another to test the actual session object.

If I had my druthers, I would love to see something like:

Code highlighting:

args_obj=None
self.assertRedirects(response, r'/labs/(?P<foobar>.+)/(.+)', get_args=args_obj)

# assuming this passes the assertion, args_obj then would ==
# args_obj = {
#    'args': ['list of un-named items'],
#    'kwargs': {dict of kwargs}

This coudl also be approached by adding the ability to get this kind of thing directly from the response object, along the lines of:

Code highlighting:

(assuming the request was '/labs/12344/test_page
> my_response.seed_url()
' '//labs//(?P<foobar>.+)//(.+)'  # which could then be matched in a redirect url match.
> my_response.url_params(1)
'test_page'
> my_response.url_params('foobar')
'12344'

Change History (0)

Note: See TracTickets for help on using tickets.
Back to Top