예제 #1
0
def test_multipart_matcher(req_file, match_file):
    @responses.activate
    def run():
        req_data = {"some": "other", "data": "fields"}
        responses.add(
            responses.POST,
            url="http://httpbin.org/post",
            match=[
                matchers.multipart_matcher(
                    files={"file_name": match_file}, data=req_data
                )
            ],
        )
        resp = requests.post(
            "http://httpbin.org/post", data=req_data, files={"file_name": req_file}
        )
        assert resp.status_code == 200

        with pytest.raises(TypeError):
            responses.add(
                responses.POST,
                url="http://httpbin.org/post",
                match=[matchers.multipart_matcher(files={})],
            )

    run()
    assert_reset()
예제 #2
0
    def test_invocation_index(self):
        @responses.activate(registry=OrderedRegistry)
        def run():
            responses.add(
                responses.GET,
                "http://twitter.com/api/1/foobar",
                status=666,
            )
            responses.add(
                responses.GET,
                "http://twitter.com/api/1/foobar",
                status=667,
            )
            responses.add(
                responses.GET,
                "http://twitter.com/api/1/foobar",
                status=668,
            )
            responses.add(
                responses.GET,
                "http://twitter.com/api/1/foobar",
                status=669,
            )

            resp = requests.get("http://twitter.com/api/1/foobar")
            assert resp.status_code == 666
            resp = requests.get("http://twitter.com/api/1/foobar")
            assert resp.status_code == 667
            resp = requests.get("http://twitter.com/api/1/foobar")
            assert resp.status_code == 668
            resp = requests.get("http://twitter.com/api/1/foobar")
            assert resp.status_code == 669

        run()
        assert_reset()
예제 #3
0
def test_fragment_identifier_matcher_error():
    @responses.activate
    def run():
        responses.add(
            responses.GET,
            "http://example.com/",
            match=[matchers.fragment_identifier_matcher("test=1")],
        )
        responses.add(
            responses.GET,
            "http://example.com/",
            match=[matchers.fragment_identifier_matcher(None)],
        )

        with pytest.raises(ConnectionError) as excinfo:
            requests.get("http://example.com/#test=2")

        msg = str(excinfo.value)
        assert (
            "URL fragment identifier is different: test=1 doesn't match test=2"
        ) in msg
        assert (
            "URL fragment identifier is different: None doesn't match test=2"
        ) in msg

    run()
    assert_reset()
예제 #4
0
def test_request_matches_headers():
    @responses.activate
    def run():
        url = "http://example.com/"
        responses.add(
            method=responses.GET,
            url=url,
            json={"success": True},
            match=[matchers.header_matcher({"Accept": "application/json"})],
        )

        responses.add(
            method=responses.GET,
            url=url,
            body="success",
            match=[matchers.header_matcher({"Accept": "text/plain"})],
        )

        # the actual request can contain extra headers (requests always adds some itself anyway)
        resp = requests.get(
            url, headers={"Accept": "application/json", "Accept-Charset": "utf-8"}
        )
        assert_response(resp, body='{"success": true}', content_type="application/json")

        resp = requests.get(url, headers={"Accept": "text/plain"})
        assert_response(resp, body="success", content_type="text/plain")

    run()
    assert_reset()
예제 #5
0
def test_request_matches_params():
    @responses.activate
    def run():
        url = "http://example.com/test"
        params = {"hello": "world", "I am": "a big test"}
        responses.add(
            method=responses.GET,
            url=url,
            body="test",
            match=[matchers.query_param_matcher(params)],
            match_querystring=False,
        )

        # exchange parameter places for the test
        params = {
            "I am": "a big test",
            "hello": "world",
        }
        resp = requests.get(url, params=params)

        constructed_url = r"http://example.com/test?I+am=a+big+test&hello=world"
        assert resp.url == constructed_url
        assert resp.request.url == constructed_url

        resp_params = getattr(resp.request, "params")
        assert resp_params == params

    run()
    assert_reset()
예제 #6
0
def test_query_string_matcher_raises():
    """
    Validate that Exception is raised if request does not match responses.matchers
        validate matchers.query_string_matcher
            :return: None
    """

    def run():
        with responses.RequestsMock(assert_all_requests_are_fired=False) as rsps:
            rsps.add(
                "GET",
                "http://111.com",
                match=[matchers.query_string_matcher("didi=pro")],
            )

            with pytest.raises(ConnectionError) as excinfo:
                requests.get("http://111.com", params={"test": "1", "didi": "pro"})

            msg = str(excinfo.value)
            assert (
                "Query string doesn't match. {didi: pro, test: 1} doesn't match {didi: pro}"
                in msg
            )

    run()
    assert_reset()
예제 #7
0
def test_query_param_matcher_loose_fail():
    @responses.activate
    def run():
        expected_query_params = {"does_not_exist": "test"}
        responses.add(
            responses.GET,
            "https://example.com/",
            match=[
                matchers.query_param_matcher(expected_query_params, strict_match=False),
            ],
        )
        with pytest.raises(ConnectionError) as exc:
            requests.get(
                "https://example.com",
                params={"only_one_param": "test", "second": "param"},
            )

        assert (
            "- GET https://example.com/ Parameters do not match. {} doesn't"
            " match {does_not_exist: test}\n"
            "You can use `strict_match=True` to do a strict parameters check."
        ) in str(exc.value)

    run()
    assert_reset()
예제 #8
0
    def test_empty_registry(self):
        @responses.activate(registry=OrderedRegistry)
        def run():
            with pytest.raises(ConnectionError):
                requests.get("http://twitter.com/api/1/foobar")

        run()
        assert_reset()
예제 #9
0
def test_registry_reset():
    def run():
        class CustomRegistry(registries.FirstMatchRegistry):
            pass

        with responses.RequestsMock(assert_all_requests_are_fired=False,
                                    registry=CustomRegistry) as rsps:
            rsps.get_registry().reset()
            assert not rsps.registered()

    run()
    assert_reset()
예제 #10
0
def test_set_registry_context_manager():
    def run():
        class CustomRegistry(registries.FirstMatchRegistry):
            pass

        with responses.RequestsMock(assert_all_requests_are_fired=False,
                                    registry=CustomRegistry) as rsps:
            assert type(rsps.get_registry()) == CustomRegistry
            assert type(
                responses.mock.get_registry()) == registries.FirstMatchRegistry

    run()
    assert_reset()
예제 #11
0
def test_request_matches_headers_strict_match():
    @responses.activate
    def run():
        url = "http://example.com/"
        responses.add(
            method=responses.GET,
            url=url,
            body="success",
            match=[
                matchers.header_matcher({"Accept": "text/plain"}, strict_match=True)
            ],
        )

        # requests will add some extra headers of its own, so we have to use prepared requests
        session = requests.Session()

        # make sure we send *just* the header we're expectin
        prepped = session.prepare_request(
            requests.Request(
                method="GET",
                url=url,
            )
        )
        prepped.headers.clear()
        prepped.headers["Accept"] = "text/plain"

        resp = session.send(prepped)
        assert_response(resp, body="success", content_type="text/plain")

        # include the "Accept-Charset" header, which will fail to match
        prepped = session.prepare_request(
            requests.Request(
                method="GET",
                url=url,
            )
        )
        prepped.headers.clear()
        prepped.headers["Accept"] = "text/plain"
        prepped.headers["Accept-Charset"] = "utf-8"

        with pytest.raises(ConnectionError) as excinfo:
            session.send(prepped)

        msg = str(excinfo.value)
        assert (
            "Headers do not match: {Accept: text/plain, Accept-Charset: utf-8} "
            "doesn't match {Accept: text/plain}"
        ) in msg

    run()
    assert_reset()
예제 #12
0
def test_fragment_identifier_matcher():
    @responses.activate
    def run():
        responses.add(
            responses.GET,
            "http://example.com",
            match=[matchers.fragment_identifier_matcher("test=1&foo=bar")],
            body=b"test",
        )

        resp = requests.get("http://example.com#test=1&foo=bar")
        assert_response(resp, "test")

    run()
    assert_reset()
예제 #13
0
def test_query_params_numbers():
    @responses.activate
    def run():
        expected_query_params = {"float": 5.0, "int": 2}
        responses.add(
            responses.GET,
            "https://example.com/",
            match=[
                matchers.query_param_matcher(expected_query_params),
            ],
        )
        requests.get("https://example.com", params=expected_query_params)

    run()
    assert_reset()
예제 #14
0
def test_set_registry_not_empty():
    class CustomRegistry(registries.FirstMatchRegistry):
        pass

    @responses.activate
    def run():
        url = "http://fizzbuzz/foo"
        responses.add(method=responses.GET, url=url)
        with pytest.raises(AttributeError) as excinfo:
            responses.mock._set_registry(CustomRegistry)
        msg = str(excinfo.value)
        assert "Cannot replace Registry, current registry has responses" in msg

    run()
    assert_reset()
예제 #15
0
def test_set_registry():
    class CustomRegistry(registries.FirstMatchRegistry):
        pass

    @responses.activate(registry=CustomRegistry)
    def run_with_registry():
        assert type(responses.mock.get_registry()) == CustomRegistry

    @responses.activate
    def run():
        # test that registry does not leak to another test
        assert type(
            responses.mock.get_registry()) == registries.FirstMatchRegistry

    run_with_registry()
    run()
    assert_reset()
예제 #16
0
def test_query_param_matcher_loose():
    @responses.activate
    def run():
        expected_query_params = {"only_one_param": "test"}
        responses.add(
            responses.GET,
            "https://example.com/",
            match=[
                matchers.query_param_matcher(expected_query_params, strict_match=False),
            ],
        )
        requests.get(
            "https://example.com", params={"only_one_param": "test", "second": "param"}
        )

    run()
    assert_reset()
예제 #17
0
def test_request_matches_post_params():
    @responses.activate
    def run(deprecated):
        if deprecated:
            json_params_matcher = getattr(responses, "json_params_matcher")
            urlencoded_params_matcher = getattr(responses, "urlencoded_params_matcher")
        else:
            json_params_matcher = matchers.json_params_matcher
            urlencoded_params_matcher = matchers.urlencoded_params_matcher

        responses.add(
            method=responses.POST,
            url="http://example.com/",
            body="one",
            match=[json_params_matcher({"page": {"name": "first", "type": "json"}})],
        )
        responses.add(
            method=responses.POST,
            url="http://example.com/",
            body="two",
            match=[urlencoded_params_matcher({"page": "second", "type": "urlencoded"})],
        )

        resp = requests.request(
            "POST",
            "http://example.com/",
            headers={"Content-Type": "x-www-form-urlencoded"},
            data={"page": "second", "type": "urlencoded"},
        )
        assert_response(resp, "two")

        resp = requests.request(
            "POST",
            "http://example.com/",
            headers={"Content-Type": "application/json"},
            json={"page": {"name": "first", "type": "json"}},
        )
        assert_response(resp, "one")

    with pytest.deprecated_call():
        run(deprecated=True)
        assert_reset()

    run(deprecated=False)
    assert_reset()
예제 #18
0
def test_query_string_matcher():
    @responses.activate
    def run():
        url = "http://example.com?test=1&foo=bar"
        responses.add(
            responses.GET,
            url,
            body=b"test",
            match=[matchers.query_string_matcher("test=1&foo=bar")],
        )
        resp = requests.get("http://example.com?test=1&foo=bar")
        assert_response(resp, "test")
        resp = requests.get("http://example.com?foo=bar&test=1")
        assert_response(resp, "test")
        resp = requests.get("http://example.com/?foo=bar&test=1")
        assert_response(resp, "test")

    run()
    assert_reset()
예제 #19
0
def test_fragment_identifier_matcher_and_match_querystring():
    @responses.activate
    def run():
        url = "http://example.com?ab=xy&zed=qwe#test=1&foo=bar"
        responses.add(
            responses.GET,
            url,
            match_querystring=True,
            match=[matchers.fragment_identifier_matcher("test=1&foo=bar")],
            body=b"test",
        )

        # two requests to check reversed order of fragment identifier
        resp = requests.get("http://example.com?ab=xy&zed=qwe#test=1&foo=bar")
        assert_response(resp, "test")
        resp = requests.get("http://example.com?zed=qwe&ab=xy#foo=bar&test=1")
        assert_response(resp, "test")

    run()
    assert_reset()
예제 #20
0
def test_request_matches_headers_no_match():
    @responses.activate
    def run():
        url = "http://example.com/"
        responses.add(
            method=responses.GET,
            url=url,
            json={"success": True},
            match=[matchers.header_matcher({"Accept": "application/json"})],
        )

        with pytest.raises(ConnectionError) as excinfo:
            requests.get(url, headers={"Accept": "application/xml"})

        msg = str(excinfo.value)
        assert (
            "Headers do not match: {Accept: application/xml} doesn't match "
            "{Accept: application/json}"
        ) in msg

    run()
    assert_reset()
예제 #21
0
    def test_not_match(self):
        @responses.activate(registry=OrderedRegistry)
        def run():
            responses.add(
                responses.GET,
                "http://twitter.com/api/1/foobar",
                json={"msg": "not found"},
                status=667,
            )
            responses.add(
                responses.GET,
                "http://twitter.com/api/1/barfoo",
                json={"msg": "not found"},
                status=404,
            )
            responses.add(
                responses.GET,
                "http://twitter.com/api/1/foobar",
                json={"msg": "OK"},
                status=200,
            )

            resp = requests.get("http://twitter.com/api/1/foobar")
            assert resp.status_code == 667

            with pytest.raises(ConnectionError) as excinfo:
                requests.get("http://twitter.com/api/1/foobar")

            msg = str(excinfo.value)
            assert (
                "- GET http://twitter.com/api/1/barfoo Next 'Response' in the "
                "order doesn't match due to the following reason: URL does not match"
            ) in msg

        run()
        assert_reset()
예제 #22
0
def test_urlencoded_params_matcher_blank():
    @responses.activate
    def run():
        responses.add(
            method=responses.POST,
            url="http://example.com/",
            body="three",
            match=[
                matchers.urlencoded_params_matcher(
                    {"page": "", "type": "urlencoded"}, allow_blank=True
                )
            ],
        )

        resp = requests.request(
            "POST",
            "http://example.com/",
            headers={"Content-Type": "x-www-form-urlencoded"},
            data={"page": "", "type": "urlencoded"},
        )
        assert_response(resp, "three")

    run()
    assert_reset()
예제 #23
0
def test_request_matches_empty_body():
    def run():
        with responses.RequestsMock(assert_all_requests_are_fired=True) as rsps:
            # test that both json and urlencoded body are empty in matcher and in request
            rsps.add(
                method=responses.POST,
                url="http://example.com/",
                body="one",
                match=[matchers.json_params_matcher(None)],
            )

            rsps.add(
                method=responses.POST,
                url="http://example.com/",
                body="two",
                match=[matchers.urlencoded_params_matcher(None)],
            )

            resp = requests.request("POST", "http://example.com/")
            assert_response(resp, "one")

            resp = requests.request(
                "POST",
                "http://example.com/",
                headers={"Content-Type": "x-www-form-urlencoded"},
            )
            assert_response(resp, "two")

        with responses.RequestsMock(assert_all_requests_are_fired=False) as rsps:
            # test exception raise if matcher body is None but request data is not None
            rsps.add(
                method=responses.POST,
                url="http://example.com/",
                body="one",
                match=[matchers.json_params_matcher(None)],
            )

            with pytest.raises(ConnectionError) as excinfo:
                requests.request(
                    "POST",
                    "http://example.com/",
                    json={"my": "data"},
                    headers={"Content-Type": "application/json"},
                )

            msg = str(excinfo.value)
            assert "request.body doesn't match: {my: data} doesn't match {}" in msg

        with responses.RequestsMock(assert_all_requests_are_fired=False) as rsps:
            rsps.add(
                method=responses.POST,
                url="http://example.com/",
                body="two",
                match=[matchers.urlencoded_params_matcher(None)],
            )
            with pytest.raises(ConnectionError) as excinfo:
                requests.request(
                    "POST",
                    "http://example.com/",
                    headers={"Content-Type": "x-www-form-urlencoded"},
                    data={"page": "second", "type": "urlencoded"},
                )
            msg = str(excinfo.value)
            assert (
                "request.body doesn't match: {page: second, type: urlencoded} doesn't match {}"
                in msg
            )

    run()
    assert_reset()
예제 #24
0
def test_fail_matchers_error():
    """
    Validate that Exception is raised if request does not match responses.matchers
        validate matchers.urlencoded_params_matcher
        validate matchers.json_params_matcher
        validate matchers.query_param_matcher
        validate matchers.request_kwargs_matcher
    :return: None
    """

    def run():
        with responses.RequestsMock(assert_all_requests_are_fired=False) as rsps:
            rsps.add(
                "POST",
                "http://example.com",
                match=[matchers.urlencoded_params_matcher({"foo": "bar"})],
            )
            rsps.add(
                "POST",
                "http://example.com",
                match=[matchers.json_params_matcher({"fail": "json"})],
            )

            with pytest.raises(ConnectionError) as excinfo:
                requests.post("http://example.com", data={"id": "bad"})

            msg = str(excinfo.value)
            assert (
                "request.body doesn't match: {id: bad} doesn't match {foo: bar}" in msg
            )

            assert (
                "request.body doesn't match: JSONDecodeError: Cannot parse request.body"
                in msg
            )

        with responses.RequestsMock(assert_all_requests_are_fired=False) as rsps:
            rsps.add(
                "GET",
                "http://111.com",
                match=[matchers.query_param_matcher({"my": "params"})],
            )

            rsps.add(
                method=responses.GET,
                url="http://111.com/",
                body="two",
                match=[matchers.json_params_matcher({"page": "one"})],
            )

            with pytest.raises(ConnectionError) as excinfo:
                requests.get(
                    "http://111.com", params={"id": "bad"}, json={"page": "two"}
                )

            msg = str(excinfo.value)
            assert (
                "Parameters do not match. {id: bad} doesn't match {my: params}" in msg
            )
            assert (
                "request.body doesn't match: {page: two} doesn't match {page: one}"
                in msg
            )

        with responses.RequestsMock(assert_all_requests_are_fired=False) as rsps:
            req_kwargs = {
                "stream": True,
                "verify": False,
            }
            rsps.add(
                "GET",
                "http://111.com",
                match=[matchers.request_kwargs_matcher(req_kwargs)],
            )

            with pytest.raises(ConnectionError) as excinfo:
                requests.get("http://111.com", stream=True)

            msg = str(excinfo.value)
            assert (
                "Arguments don't match: "
                "{stream: True, verify: True} doesn't match {stream: True, verify: False}"
            ) in msg

    run()
    assert_reset()
예제 #25
0
def test_multipart_matcher_fail():
    """
    Validate that Exception is raised if request does not match responses.matchers
        validate matchers.multipart_matcher
    :return: None
    """

    def run():
        # different file contents
        with responses.RequestsMock(assert_all_requests_are_fired=False) as rsps:
            req_data = {"some": "other", "data": "fields"}
            req_files = {"file_name": b"Old World!"}
            rsps.add(
                responses.POST,
                url="http://httpbin.org/post",
                match=[matchers.multipart_matcher(req_files, data=req_data)],
            )

            with pytest.raises(ConnectionError) as excinfo:
                requests.post(
                    "http://httpbin.org/post",
                    data=req_data,
                    files={"file_name": b"New World!"},
                )

            msg = str(excinfo.value)
            assert "multipart/form-data doesn't match. Request body differs." in msg

            assert (
                r'\r\nContent-Disposition: form-data; name="file_name"; '
                r'filename="file_name"\r\n\r\nOld World!\r\n'
            ) in msg
            assert (
                r'\r\nContent-Disposition: form-data; name="file_name"; '
                r'filename="file_name"\r\n\r\nNew World!\r\n'
            ) in msg

        # x-www-form-urlencoded request
        with responses.RequestsMock(assert_all_requests_are_fired=False) as rsps:
            req_data = {"some": "other", "data": "fields"}
            req_files = {"file_name": b"Old World!"}
            rsps.add(
                responses.POST,
                url="http://httpbin.org/post",
                match=[matchers.multipart_matcher(req_files, data=req_data)],
            )

            with pytest.raises(ConnectionError) as excinfo:
                requests.post("http://httpbin.org/post", data=req_data)

            msg = str(excinfo.value)
            assert (
                "multipart/form-data doesn't match. Request headers['Content-Type'] is different."
                in msg
            )
            assert (
                "application/x-www-form-urlencoded isn't equal to multipart/form-data; boundary="
                in msg
            )

        # empty body request
        with responses.RequestsMock(assert_all_requests_are_fired=False) as rsps:
            req_files = {"file_name": b"Old World!"}
            rsps.add(
                responses.POST,
                url="http://httpbin.org/post",
                match=[matchers.multipart_matcher(req_files)],
            )

            with pytest.raises(ConnectionError) as excinfo:
                requests.post("http://httpbin.org/post")

            msg = str(excinfo.value)
            assert "Request is missing the 'Content-Type' header" in msg

    run()
    assert_reset()