Exemple #1
0
def _read_expected_cookies(session, rspec, test_block_config):
    """
    Read cookies to inject into request, ignoring others which are present

    Args:
        session (Session): session object
        rspec (dict): test spec
        test_block_config (dict): config available for test

    Returns:
        dict: cookies to use in request, if any
    """
    # Need to do this down here - it is separate from getting request args as
    # it depends on the state of the session
    existing_cookies = session.cookies.get_dict()
    cookies_to_use = format_keys(
        rspec.get("cookies", None), test_block_config["variables"]
    )

    if cookies_to_use is None:
        logger.debug("No cookies specified in request, sending all")
        return None
    elif cookies_to_use in ([], {}):
        logger.debug("Not sending any cookies with request")
        return {}

    def partition(pred, iterable):
        """From itertools documentation"""
        t1, t2 = tee(iterable)
        return list(filterfalse(pred, t1)), list(filter(pred, t2))

    # Cookies are either a single list item, specitying which cookie to send, or
    # a mapping, specifying cookies to override
    expected, extra = partition(lambda x: isinstance(x, dict), cookies_to_use)

    missing = set(expected) - set(existing_cookies.keys())

    if missing:
        logger.error("Missing cookies")
        raise exceptions.MissingCookieError(
            "Tried to use cookies '{}' in request but only had '{}' available".format(
                expected, existing_cookies
            )
        )

    # 'extra' should be a list of dictionaries - merge them into one here
    from_extra = {k: v for mapping in extra for (k, v) in mapping.items()}

    if len(extra) != len(from_extra):
        logger.error("Duplicate cookie override values specified")
        raise exceptions.DuplicateCookieError(
            "Tried to override the value of a cookie multiple times in one request"
        )

    overwritten = [i for i in expected if i in from_extra]

    if overwritten:
        logger.error("Duplicate cookies found in request")
        raise exceptions.DuplicateCookieError(
            "Asked to use cookie {} from previous request but also redefined it as {}".format(
                overwritten, from_extra
            )
        )

    from_cookiejar = {c: existing_cookies.get(c) for c in expected}

    return deep_dict_merge(from_cookiejar, from_extra)
Exemple #2
0
    def __init__(self, session, rspec, test_block_config):
        """Prepare request

        Args:
            session (requests.Session): existing session
            rspec (dict): test spec
            test_block_config (dict): Any configuration for this the block of
                tests

        Raises:
            UnexpectedKeysError: If some unexpected keys were used in the test
                spec. Only valid keyword args to requests can be passed
        """

        if "meta" in rspec:
            meta = rspec.pop("meta")
            if meta and "clear_session_cookies" in meta:
                session.cookies.clear_session_cookies()

        expected = {
            "method",
            "url",
            "headers",
            "data",
            "params",
            "auth",
            "json",
            "verify",
            "files",
            "stream",
            "timeout",
            "cookies",
            "cert",
            # "hooks",
        }

        check_expected_keys(expected, rspec)

        request_args = get_request_args(rspec, test_block_config)

        # Need to do this down here - it is separate from getting request args as
        # it depends on the state of the session
        if "cookies" in rspec:
            existing_cookies = session.cookies.get_dict()
            missing = set(rspec["cookies"]) - set(existing_cookies.keys())
            if missing:
                logger.error("Missing cookies")
                raise exceptions.MissingCookieError(
                    "Tried to use cookies '{}' in request but only had '{}' available"
                    .format(rspec["cookies"], existing_cookies))
            request_args["cookies"] = {
                c: existing_cookies.get(c)
                for c in rspec["cookies"]
            }

        logger.debug("Request args: %s", request_args)

        request_args.update(allow_redirects=False)

        self._request_args = request_args

        # There is no way using requests to make a prepared request that will
        # not follow redirects, so instead we have to do this. This also means
        # that we can't have the 'pre-request' hook any more because we don't
        # create a prepared request.

        def prepared_request():
            # If there are open files, create a context manager around each so
            # they will be closed at the end of the request.
            with ExitStack() as stack:
                stack.enter_context(
                    _set_cookies_for_request(session, request_args))
                self._request_args.update(self._get_file_arguments(stack))
                return session.request(**self._request_args)

        self._prepared = prepared_request