Question

I'm testing my Flask app.

In summary, here is my question(s):

1) My final url assertion in the block of code below fails. According to Twill, it fails because the actual url is '/auth/login'. In other words, the user was NOT redirected to the protected admin page. Why?

2) How can I include the "/?next='admin'" request argument in my url assertion? In other words, is there a way--via Twill or any Pythonic means--to test the 'next' argument resolved correctly?

3) In functional testing, is there any other way to show a redirect works beyond just asserting a 301 status code?

Here's the Twill related part of my script...

   t.browser.go(t.url("/auth/login/?next=%2Fadmin%2F"))
   url("/auth/login/?next=%2Fadmin%2F")

Here's the resultant traceback:

   TwillAssertionError: current url is 'http://127.0.0.1:5000/auth/login/?next=%2Fadmin%2F';
does not match '/auth/login/?next=%2Fadmin%2F'

NOTE: Weirdly, asserting a 200 status code after the 'go' command does not return any kind of error. I'd like to show that, after logging into the above URL, that the final URL is, indeed, the admin page. Like so...

The test I'd like to run without any fails, but can't...

def test_redirect_via_url(self):        
        with Twill(self.app, port=8080) as t:

            #: go to admin page before logging in...
            t.browser.go(t.url("/admin"))

            #: assert admin url redirected to login url
            url('/auth/login')

            #: The above assertion works, but...
            #: why can't I assert this URL..a 'next' argument...?
            #: "/auth/login/?next=%2Fadmin%2F"
            #: that's what actually appears in the browser's address bar

            #: In any regard, at the '/auth/login' url, let's login
            fv("1", "username", "test")
            fv("1", "password", "welcome1")
            submit()

            #: Now I want to show my app actually redirects to the protected admin page...
            #: which should have a URL of localhost/admin
            url('/admin')

            #: The above url assertion fails.  The actual url after submit is still '/auth/login'

Was it helpful?

Solution

The reason is that twill.commands.url asserts that the URL it is passed matches the browser's URL by converting it to a regular expression and matching against it. This results in /auth/login/?next=%2Fadmin%2F being translated to:

/auth/login       # Match this literal string
/?                # followed by zero or one slash
next=%2Fadmin%2F  # followed by this literal string

Which means that it will match /auth/login/next=%2Fadmin%2F or /auth/loginnext=%2Fadmin%2F but not /auth/login/?next=%2Fadmin%2F. A work-around is to escape the question mark (url(r"/auth/login/\?next=%2Fadmin%2F") should work).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top