test_oauth2.py 3.8 KB
Newer Older
1 2 3 4 5
# -*- coding: utf-8 -*-
"""Tests for OAuth2 permission delegation."""

from urlparse import urlparse, parse_qsl

6 7 8 9
from common.test.acceptance.pages.lms.oauth2_confirmation import OAuth2Confirmation
from common.test.acceptance.pages.lms.auto_auth import AutoAuthPage
from common.test.acceptance.tests.helpers import AcceptanceTest

10

11
class OAuth2PermissionDelegationTests(AcceptanceTest):
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
    """
    Tests for acceptance/denial of permission delegation requests.
    """

    def setUp(self):
        super(OAuth2PermissionDelegationTests, self).setUp()
        self.oauth_page = OAuth2Confirmation(self.browser)

    def _auth(self):
        """Authenticate the user."""
        AutoAuthPage(self.browser).visit()

    def _qs(self, url):
        """Parse url's querystring into a dict."""
        return dict(parse_qsl(urlparse(url).query))

    def test_error_for_invalid_scopes(self):
        """Requests for invalid scopes throw errors."""
        self._auth()
        self.oauth_page.scopes = ('email', 'does-not-exist')
        assert self.oauth_page.visit()

        self.assertTrue(self.oauth_page.has_error)
        self.assertIn('not a valid scope', self.oauth_page.error_message)

    def test_cancelling_redirects(self):
        """
        If you cancel the request, you're redirected to the redirect_url with a
        denied query param.
        """
        self._auth()
        assert self.oauth_page.visit()
        self.oauth_page.cancel()

Adam committed
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
        def check_redirect():
            """
            Checks that the page correctly redirects to a url with a
            denied query param.
            """
            query = self._qs(self.browser.current_url)
            return 'access_denied' in query['error']

        def check_redirect_chrome():
            """
            Similar to `check_redirect`, but, due to a bug in ChromeDriver,
            we use `self.browser.title` here instead of `self.browser.current_url`
            """
            query = self._qs(self.browser.title)
            return 'access_denied' in query['error']

62 63
        # This redirects to an invalid URI. For chrome verify title, current_url otherwise
        if self.browser.name == 'chrome':
Adam committed
64
            self.oauth_page.wait_for(check_redirect_chrome, 'redirected to invalid URL (chrome)')
65
        else:
Adam committed
66
            self.oauth_page.wait_for(check_redirect, 'redirected to invalid URL')
67 68 69 70 71 72 73 74 75 76

    def test_accepting_redirects(self):
        """
        If you accept the request, you're redirected to the redirect_url with
        the correct query params.
        """
        self._auth()
        assert self.oauth_page.visit()

        # This redirects to an invalid URI.
77
        self.oauth_page.confirm()
78 79 80
        self.oauth_page.wait_for_element_absence(
            'input[name=authorize]', 'Authorization button is not present'
        )
81

82 83 84 85
        def check_query_string():
            """
            Checks that 'code' appears in the browser's current url.
            """
86
            query = self._qs(self.browser.current_url)
87 88 89 90 91 92 93 94 95 96 97 98 99
            return 'code' in query

        def check_query_string_chrome():
            """
            Similar to check_query_string, but, due to a bug in ChromeDriver,
            when chrome is on an invalid URI, `self.browser.current_url` outputs
            "data:text/html,chromewebdata" instead of the current URI.

            However, since the query string is present in the `title`, we use
            that for chrome.
            """
            query = self._qs(self.browser.title)
            return 'code' in query
100

101 102 103 104 105 106 107 108
        if self.browser.name == 'chrome':
            self.oauth_page.wait_for(
                check_query_string_chrome, 'redirected with correct query parameters (chrome)'
            )
        else:
            self.oauth_page.wait_for(
                check_query_string, 'redirected with correct query parameters'
            )