Exemplo n.º 1
0
    def test_publisher_connect_pat(self):
        """validate publisher issues a pat-authorization header"""
        #
        # Verify that a publisher will issue an `Authorization` header when
        # configure to use a personal access token.

        token = 'dummy-pat-value'
        expected_auth_value = 'Bearer {}'.format(token)

        config = self.config.clone()
        config.confluence_publish_token = token

        val = {
            'size': 1,
            'results': [{
                'name': 'My Space',
                'type': 'global',
            }],
        }

        with mock_confluence_instance(config) as daemon, \
                autocleanup_publisher(ConfluencePublisher) as publisher:
            daemon.register_get_rsp(200, val)

            publisher.init(config)
            publisher.connect()

            first_request = daemon.pop_get_request()
            self.assertIsNotNone(first_request)
            _, headers = first_request
            auth_header = headers.get('Authorization')
            if not auth_header:
                auth_header = headers.get('authorization')
            self.assertIsNotNone(auth_header)
            self.assertEqual(auth_header, expected_auth_value)
    def test_publisher_page_base_id_parent_name(self):
        """validate publisher will search for parent page by name"""
        #
        # Verify that a publisher will find a base (pages) identifier, based
        # off a configured parent page name.

        expected_page_name = 'refname-31421'

        config = self.config.clone()
        config.confluence_parent_page = expected_page_name

        with mock_confluence_instance(config) as daemon, \
                autocleanup_publisher(ConfluencePublisher) as publisher:
            daemon.register_get_rsp(200, self.std_space_connect_rsp)

            publisher.init(config)
            publisher.connect()

            # consume connect request
            self.assertIsNotNone(daemon.pop_get_request())

            # prepare response for a page fetch
            expected_page_id = '245'

            page_search_fetch_rsp = {
                'size':
                1,
                'results': [{
                    'id': expected_page_id,
                    'title': 'mock page',
                    'type': 'page',
                }],
            }
            daemon.register_get_rsp(200, page_search_fetch_rsp)

            # perform base page id fetch request
            base_id = publisher.get_base_page_id()

            # check expected page id returned
            self.assertEqual(base_id, expected_page_id)

            # check that the provided page id is set in the request
            fetch_req = daemon.pop_get_request()
            self.assertIsNotNone(fetch_req)
            req_path, _ = fetch_req

            expected_opt = 'title={}'.format(expected_page_name)
            self.assertTrue(req_path.startswith('/rest/api/content'))
            self.assertTrue(expected_opt in expected_opt)

            # verify that no other request was made
            daemon.check_unhandled_requests()
Exemplo n.º 3
0
    def test_publisher_connect_handle_proxy_permission_error(self):
        """validate publisher reports a proxy-permission error"""
        #
        # Verify that the publisher will report a tailored error message when a
        # configured proxy reports a permission issue.

        with mock_confluence_instance(self.config) as daemon, \
                autocleanup_publisher(ConfluencePublisher) as publisher:
            daemon.register_get_rsp(407, None)

            publisher.init(self.config)

            with self.assertRaises(ConfluenceProxyPermissionError):
                publisher.connect()
Exemplo n.º 4
0
    def test_publisher_connect_handle_authentication_error(self):
        """validate publisher reports an authentication error"""
        #
        # Verify that the publisher will report a tailored error message when a
        # Confluence instance reports an authentication issue.

        with mock_confluence_instance(self.config) as daemon, \
                autocleanup_publisher(ConfluencePublisher) as publisher:
            daemon.register_get_rsp(401, None)

            publisher.init(self.config)

            with self.assertRaises(ConfluenceAuthenticationFailedUrlError):
                publisher.connect()
Exemplo n.º 5
0
    def test_publisher_connect_bad_response_code(self):
        """validate publisher can handle bad response code"""
        #
        # Verify that the initial connection event for a publisher can safely
        # handle a 500 server error on a connection.

        with mock_confluence_instance(self.config) as daemon, \
                autocleanup_publisher(ConfluencePublisher) as publisher:
            daemon.register_get_rsp(500, None)

            publisher.init(self.config)

            with self.assertRaises(ConfluenceBadServerUrlError):
                publisher.connect()
Exemplo n.º 6
0
    def test_publisher_connect_invalid_json(self):
        """validate publisher can handle non-json data"""
        #
        # Verify that the initial connection event for a publisher can safely
        # handle non-JSON data returned from a configured instance (either a
        # non-Confluence instance or a proxy response).

        with mock_confluence_instance(self.config) as daemon, \
                autocleanup_publisher(ConfluencePublisher) as publisher:
            daemon.register_get_rsp(200, 'Welcome to my website.')

            publisher.init(self.config)

            with self.assertRaises(ConfluenceBadServerUrlError):
                publisher.connect()
    def test_publisher_page_store_page_id_dryrun(self):
        """validate publisher suppress store a page by id with dryrun"""
        #
        # Verify that a publisher will handle a id-page update request
        # properly when the dryrun flag is set.

        config = self.config.clone()
        config.confluence_publish_dryrun = True

        with mock_confluence_instance(config) as daemon, \
                autocleanup_publisher(ConfluencePublisher) as publisher:
            daemon.register_get_rsp(200, self.std_space_connect_rsp)

            publisher.init(config)
            publisher.connect()

            # consume connect request
            self.assertIsNotNone(daemon.pop_get_request())

            # prepare response for a page id fetch
            expected_page_id = 2

            page_rsp = {
                'id': expected_page_id,
                'title': 'mock page',
                'type': 'page',
            }
            daemon.register_get_rsp(200, page_rsp)

            page_id = publisher.store_page_by_id('dummy-name',
                                                 expected_page_id, {})

            # check expected page id returned
            self.assertEqual(page_id, expected_page_id)

            # check that the provided page id is set in the request
            fetch_req = daemon.pop_get_request()
            self.assertIsNotNone(fetch_req)
            req_path, _ = fetch_req

            expected_request = '/rest/api/content/{}?'.format(expected_page_id)
            self.assertTrue(req_path.startswith(expected_request))

            # verify that no update request was made
            daemon.check_unhandled_requests()
Exemplo n.º 8
0
    def test_publisher_api_bind_path_default(self):
        """validate publisher includes api bind path"""
        #
        # Verify that a publisher will perform requests which target the
        # `/rest/api` endpoint.

        with mock_confluence_instance(self.config) as daemon, \
                autocleanup_publisher(ConfluencePublisher) as publisher:
            daemon.register_get_rsp(200, self.std_space_connect_rsp)

            publisher.init(self.config)
            publisher.connect()

            # connect request
            connect_req = daemon.pop_get_request()
            self.assertIsNotNone(connect_req)
            req_path, _ = connect_req
            self.assertTrue('/rest/api/' in req_path)
Exemplo n.º 9
0
    def test_publisher_connect_verify_timeout(self):
        """validate publisher timeout"""
        #
        # Verify that a non-served request from a publisher event will timeout.

        with mock_confluence_instance(self.config, ignore_requests=True), \
                autocleanup_publisher(ConfluencePublisher) as publisher:
            publisher.init(self.config)

            start = time.time()

            with self.assertRaises(ConfluenceTimeoutError):
                publisher.connect()

            end = time.time()
            diff = int(end - start)

            self.assertLessEqual(diff, self.config.confluence_timeout + 1)
Exemplo n.º 10
0
    def test_publisher_connect_unsupported_json(self):
        """validate publisher can handle unexpected json data"""
        #
        # Verify that the initial connection event for a publisher provides a
        # bit more strict error checking on the provided JSON data returned.
        # This is to help deal with a configuration which points to a
        # non-Confluence instance, but the server provides JSON data in its
        # response.

        with mock_confluence_instance(self.config) as daemon, \
                autocleanup_publisher(ConfluencePublisher) as publisher:
            publisher.init(self.config)

            # random json data
            rsp = {
                'some-data': 'hello',
            }
            daemon.register_get_rsp(200, rsp)
            with self.assertRaises(ConfluenceBadServerUrlError):
                publisher.connect()

            # data with a size field, but unrelated data
            rsp = {
                'size': 3,
                'data': [
                    'item-1',
                    'item-2',
                    'item-3',
                ],
            }
            daemon.register_get_rsp(200, rsp)
            with self.assertRaises(ConfluenceBadServerUrlError):
                publisher.connect()

            # result data not matching expected
            rsp = {
                'size': 1,
                'results': [{
                    'misc-option': 123,
                }],
            }
            daemon.register_get_rsp(200, rsp)
            with self.assertRaises(ConfluenceBadServerUrlError):
                publisher.connect()
Exemplo n.º 11
0
    def test_publisher_api_bind_path_disabled(self):
        """validate publisher can disable api bind path"""
        #
        # Verify that a publisher can perform requests disables the use of
        # the `/rest/api` endpoint.

        config = self.config.clone()
        config.confluence_publish_disable_api_prefix = True

        with mock_confluence_instance(config) as daemon, \
                autocleanup_publisher(ConfluencePublisher) as publisher:
            daemon.register_get_rsp(200, self.std_space_connect_rsp)

            publisher.init(config)
            publisher.connect()

            # connect request
            connect_req = daemon.pop_get_request()
            self.assertIsNotNone(connect_req)
            req_path, _ = connect_req
            self.assertTrue('/rest/api/' not in req_path)
    def test_publisher_page_base_id_parent_none(self):
        """validate publisher will search for parent page by name"""
        #
        # Verify that a publisher will find a base (pages) identifier, based
        # off a configured parent page name.

        with mock_confluence_instance(self.config) as daemon, \
                autocleanup_publisher(ConfluencePublisher) as publisher:
            daemon.register_get_rsp(200, self.std_space_connect_rsp)

            publisher.init(self.config)
            publisher.connect()

            # consume connect request
            self.assertIsNotNone(daemon.pop_get_request())

            # prepare response for a page fetch
            expected_page_id = '416'

            page_fetch_rsp = {
                'size':
                1,
                'results': [{
                    'id': expected_page_id,
                    'title': 'mock page',
                    'type': 'page',
                }],
            }
            daemon.register_get_rsp(200, page_fetch_rsp)

            # request base id which should return nothing, with no request
            base_id = publisher.get_base_page_id()
            self.assertIsNone(base_id)

            # verify that no other request was made
            daemon.check_unhandled_requests()
Exemplo n.º 13
0
    def test_publisher_connect_valid_space(self):
        """validate publisher can find a valid space"""
        #
        # Verify that a publisher can query a Confluence instance and cache the
        # display name for a space.

        space_name = 'My Space'

        val = {
            'size': 1,
            'results': [{
                'name': space_name,
                'type': 'global',
            }],
        }

        with mock_confluence_instance(self.config) as daemon, \
                autocleanup_publisher(ConfluencePublisher) as publisher:
            daemon.register_get_rsp(200, val)

            publisher.init(self.config)
            publisher.connect()

            self.assertEqual(publisher.space_display_name, space_name)
    def test_publisher_page_store_page_id_default(self):
        """validate publisher will store a page by id (default)"""
        #
        # Verify that a publisher can update an existing page by an
        # identifier value. By default, the update request will ensure
        # the user configures to not watch the page.

        with mock_confluence_instance(self.config) as daemon, \
                autocleanup_publisher(ConfluencePublisher) as publisher:
            daemon.register_get_rsp(200, self.std_space_connect_rsp)

            publisher.init(self.config)
            publisher.connect()

            # consume connect request
            self.assertIsNotNone(daemon.pop_get_request())

            # prepare response for a page id fetch
            expected_page_id = 4568
            mocked_version = 45

            page_fetch_rsp = {
                'id': str(expected_page_id),
                'title': 'mock page',
                'type': 'page',
                'version': {
                    'number': str(mocked_version),
                },
            }
            daemon.register_get_rsp(200, page_fetch_rsp)

            # prepare response for update event
            daemon.register_put_rsp(200, dict(page_fetch_rsp))

            # prepare response for unwatch event
            daemon.register_delete_rsp(200)

            # perform page update request
            data = {
                'content': 'dummy page data',
                'labels': [],
            }
            page_id = publisher.store_page_by_id('dummy-name',
                                                 expected_page_id, data)

            # check expected page id returned
            self.assertEqual(page_id, expected_page_id)

            # check that the provided page id is set in the request
            fetch_req = daemon.pop_get_request()
            self.assertIsNotNone(fetch_req)
            req_path, _ = fetch_req

            expected_request = '/rest/api/content/{}?'.format(expected_page_id)
            self.assertTrue(req_path.startswith(expected_request))

            # check that an update request is processed
            update_req = daemon.pop_put_request()
            self.assertIsNotNone(update_req)

            # check that the page is unwatched
            unwatch_req = daemon.pop_delete_request()
            self.assertIsNotNone(unwatch_req)
            req_path, _ = unwatch_req
            ereq = '/rest/api/user/watch/content/{}'.format(expected_page_id)
            self.assertEqual(req_path, ereq)

            # verify that no other request was made
            daemon.check_unhandled_requests()
    def test_publisher_page_store_page_id_allow_watch(self):
        """validate publisher will store a page by id (watch)"""
        #
        # Verify that a publisher can update an existing page by an
        # identifier value. Instance will be configured to watch content,
        # so any page updates should not trigger an watch event.

        config = self.config.clone()
        config.confluence_watch = True

        with mock_confluence_instance(config) as daemon, \
                autocleanup_publisher(ConfluencePublisher) as publisher:
            daemon.register_get_rsp(200, self.std_space_connect_rsp)

            publisher.init(config)
            publisher.connect()

            # consume connect request
            self.assertIsNotNone(daemon.pop_get_request())

            # prepare response for a page id fetch
            expected_page_id = 7456
            mocked_version = 28

            page_fetch_rsp = {
                'id': str(expected_page_id),
                'title': 'mock page',
                'type': 'page',
                'version': {
                    'number': str(mocked_version),
                },
            }
            daemon.register_get_rsp(200, page_fetch_rsp)

            # prepare response for update event
            daemon.register_put_rsp(200, dict(page_fetch_rsp))

            # perform page update request
            data = {
                'content': 'dummy page data',
                'labels': [],
            }
            page_id = publisher.store_page_by_id('dummy-name',
                                                 expected_page_id, data)

            # check expected page id returned
            self.assertEqual(page_id, expected_page_id)

            # check that the provided page id is set in the request
            fetch_req = daemon.pop_get_request()
            self.assertIsNotNone(fetch_req)
            req_path, _ = fetch_req

            expected_request = '/rest/api/content/{}?'.format(expected_page_id)
            self.assertTrue(req_path.startswith(expected_request))

            # check that an update request is processed
            update_req = daemon.pop_put_request()
            self.assertIsNotNone(update_req)

            # verify that no other request was made
            daemon.check_unhandled_requests()
Exemplo n.º 16
0
    def test_publisher_connect_proxy(self):
        """validate publisher can find a valid space"""
        #
        # Verify that a publisher can query a Confluence instance and cache the
        # display name for a space.

        std_space_name = 'My Default Space'
        std_rsp = {
            'size': 1,
            'results': [{
                'name': std_space_name,
                'type': 'global',
            }],
        }

        proxy_space_name = 'My Proxy Space'
        proxy_rsp = {
            'size': 1,
            'results': [{
                'name': proxy_space_name,
                'type': 'global',
            }],
        }

        try:
            with mock_confluence_instance(self.config) as default_daemon,\
                    mock_confluence_instance() as proxy_daemon:

                proxy_host, proxy_port = proxy_daemon.server_address
                proxy_url = 'http://{}:{}/'.format(proxy_host, proxy_port)

                # check default space is accessible
                default_daemon.register_get_rsp(200, std_rsp)
                proxy_daemon.register_get_rsp(200, proxy_rsp)

                with autocleanup_publisher(ConfluencePublisher) as publisher:
                    publisher.init(self.config)
                    publisher.connect()

                self.assertEqual(publisher.space_display_name, std_space_name)

                # check confluence proxy option will go through proxy instance
                config = self.config.clone()
                config.confluence_proxy = proxy_url

                default_daemon.register_get_rsp(200, std_rsp)
                proxy_daemon.register_get_rsp(200, proxy_rsp)

                with autocleanup_publisher(ConfluencePublisher) as publisher:
                    publisher.init(config)
                    publisher.connect()

                self.assertEqual(publisher.space_display_name, proxy_space_name)

                # check system proxy option will go through proxy instance
                os.environ['http_proxy'] = proxy_url

                default_daemon.register_get_rsp(200, std_rsp)
                proxy_daemon.register_get_rsp(200, proxy_rsp)

                with autocleanup_publisher(ConfluencePublisher) as publisher:
                    publisher.init(self.config)
                    publisher.connect()

                self.assertEqual(publisher.space_display_name, proxy_space_name)
        finally:
            if 'http_proxy' in os.environ:
                del os.environ['http_proxy']