Exemple #1
0
def test_fake_array(mock_data_store):
    faker = StatefulFaker(mock_data_store)

    request = RequestBuilder.from_dict(
        dict(method="get", protocol="http", path="/items", host="api.com")
    )

    schema = {"type": "array", "items": {"$ref": "#/components/schemas/item"}}

    components = {
        "schemas": {
            "item": {
                "type": "object",
                "required": ["foo", "bar"],
                "x-hmt-id-path": "itemId",
                "properties": {
                    "foo": {"type": "number"},
                    "bar": {"type": "string"},
                    "itemId": {"type": "string"},
                },
            }
        }
    }

    spec = spec_dict(
        path="/items", response_schema=schema, components=components, method="get"
    )
    spec["paths"]["/items"]["x-hmt-entity"] = "item"
    spec["paths"]["/items"]["get"]["x-hmt-operation"] = "read"

    spec = convert_to_OpenAPIObject(spec)
    mock_data_store.add_mock(OpenAPISpecification(spec, "default"))

    schema["components"] = components
    spec = OpenAPISpecification(source="default", api=spec)

    res = faker.process(spec, request)

    assert valid_schema(res.bodyAsJson, schema)
    assert 0 == len(res.bodyAsJson)

    mock_data_store["default"].item.insert({"foo": 10, "bar": "val", "itemId": "id123"})
    res = faker.process(spec, request)

    assert valid_schema(res.bodyAsJson, schema)
    assert 1 == len(res.bodyAsJson)

    mock_data_store["default"].item.insert(
        {"foo": 10, "bar": "val", "itemId": "id1234"}
    )
    res = faker.process(spec, request)

    assert valid_schema(res.bodyAsJson, schema)
    assert 2 == len(res.bodyAsJson)
Exemple #2
0
def test_sateless_faker_2(mock_data_store):
    faker = StatefulFaker(mock_data_store)

    request = RequestBuilder.from_dict(
        dict(method="get", protocol="http", path="/", host="api.com")
    )

    schema = {
        "$id": "https://example.com/person.schema.json",
        "$schema": "http://json-schema.org/draft-07/schema#",
        "title": "Person",
        "type": "object",
        "properties": {
            "firstName": {"type": "string", "description": "The person's first name."},
            "lastName": {"type": "string", "description": "The person's last name."},
            "age": {
                "description": "Age in years which must be equal to or greater than zero.",
                "type": "integer",
                "minimum": 0.0,
            },
        },
    }
    res = faker.process(
        OpenAPISpecification(source="default", api=spec(response_schema=schema)),
        request,
    )

    assert valid_schema(res.bodyAsJson, schema)
Exemple #3
0
def test_sateless_faker_3(mock_data_store):
    faker = StatefulFaker(mock_data_store)

    request = RequestBuilder.from_dict(
        dict(method="get", protocol="http", path="/", host="api.com")
    )

    schema = {
        "$id": "https://example.com/geographical-location.schema.json",
        "$schema": "http://json-schema.org/draft-07/schema#",
        "title": "Longitude and Latitude Values",
        "description": "A geographical coordinate.",
        "required": ["latitude", "longitude"],
        "type": "object",
        "properties": {
            "latitude": {"type": "number", "minimum": -90.0, "maximum": 90.0},
            "longitude": {"type": "number", "minimum": -180.0, "maximum": 180.0},
        },
    }
    res = faker.process(
        OpenAPISpecification(source="default", api=spec(response_schema=schema)),
        request,
    )

    assert valid_schema(res.bodyAsJson, schema)
Exemple #4
0
def test_clear():
    store = MockDataStore()

    store.add_mock(OpenAPISpecification(spec(), "pokemon"))
    store.add_mock(OpenAPISpecification(spec(), "another"))

    store["pokemon"]["x"] = "foo"
    store["another"]["y"] = "bar"

    assert "foo" == store["pokemon"]["x"]
    assert "bar" == store["another"]["y"]

    store.clear()

    assert store["pokemon"].get("x") is None
    assert store["another"].get("y") is None
Exemple #5
0
def test_sateless_faker_1(mock_data_store):
    faker = StatefulFaker(mock_data_store)

    request = RequestBuilder.from_dict(
        dict(method="get", protocol="http", path="/", host="api.com")
    )

    schema = {
        "type": "array",
        "items": {
            "type": "object",
            "required": ["foo", "baz"],
            "properties": {
                "foo": {"type": "number"},
                "bar": {"type": "string"},
                "baz": {"type": "string"},
            },
        },
    }
    res = faker.process(
        OpenAPISpecification(source="default", api=spec(response_schema=schema)),
        request,
    )

    assert valid_schema(res.bodyAsJson, schema)
Exemple #6
0
def test_add_mock_no_data():
    schema = {"$ref": "#/components/schemas/item"}

    components = {
        "schemas": {
            "item": {
                "type": "object",
                "required": ["foo", "baz"],
                "x-hmt-id-path": "itemId",
                "properties": {
                    "foo": {"type": "number"},
                    "bar": {"type": "string"},
                    "itemId": {"type": "string"},
                },
            }
        }
    }

    spec = spec_dict(
        path="/items/{id}", response_schema=schema, components=components, method="get"
    )
    spec["paths"]["/items/{id}"]["x-hmt-entity"] = "item"
    spec["paths"]["/items/{id}"]["get"]["x-hmt-operation"] = "read"

    spec = convert_to_OpenAPIObject(spec)

    store = MockDataStore()
    store.add_mock(OpenAPISpecification(spec, "items"))

    assert 0 == len(store["items"].item)

    store["items"].item.insert({"foo": 10, "bar": "val", "itemId": "id123"})

    assert 1 == len(store["items"].item)
    assert "val" == store["items"].item["id123"]["bar"]
Exemple #7
0
def match_request_to_openapi(
        req: Request, specs: Sequence[OpenAPISpecification]
) -> Sequence[OpenAPISpecification]:
    def _path_item_modifier(
            oai: OpenAPIObject) -> Callable[[PathItem], PathItem]:
        def __path_item_modifier(path_item: PathItem) -> PathItem:
            return reduce(
                lambda a, b: b(a),
                [
                    keep_method_if_required_header_parameters_are_present(
                        req, oai),
                    keep_method_if_required_query_parameters_are_present(
                        req, oai),
                    ##### keep_method_if_required_request_body_is_present
                    ##### should be uncommented in a separate PR
                    ##### it breaks the logic in the new schemabuilder
                    ##### but it should be reimplemented
                    ##### now, the issue is that API requests will not
                    ##### have their body validated
                    ##### as there are so few API requests that require body
                    ##### validation for mocking, this is a small loss
                    ##### but should still be acknowledged and fixed when
                    ##### someone has time
                    # keep_method_if_required_request_body_is_present(req, oai),
                ],
                get_path_item_with_method(req.method.value, path_item),
            )

        return __path_item_modifier

    def _oai_modifier(oai: OpenAPIObject) -> OpenAPIObject:
        return paths_o.Values().modify(_path_item_modifier(oai))(replace(
            oai,
            paths={
                n: o
                for n, o in oai.paths.items() if matches(
                    truncate_path(req.pathname, oai, req),
                    n,
                    o,
                    req.method.value,
                    oai,
                )
            },
        ))

    specs_with_matching_urls = {
        spec.source: spec.api
        for spec in specs
        if len(match_urls(req.protocol.value, req.host, spec.api)) > 0
    }

    filtered = {
        k: _oai_modifier(v)
        for k, v in specs_with_matching_urls.items()
    }

    return [
        OpenAPISpecification(api, source)
        for (source, api) in filtered.items()
    ]
Exemple #8
0
def test_sateless_faker_4(mock_data_store):
    faker = StatefulFaker(mock_data_store)

    request = RequestBuilder.from_dict(
        dict(method="get", protocol="http", path="/", host="api.com"))

    schema = {
        "$id": "https://example.com/arrays.schema.json",
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description":
        "A representation of a person, company, organization, or place",
        "type": "object",
        "properties": {
            "fruits": {
                "type": "array",
                "items": {
                    "type": "string"
                }
            },
            "vegetables": {
                "type": "array",
                "items": {
                    "$ref": "#/components/schemas/veggie"
                },
            },
        },
    }
    components = {
        "schemas": {
            "veggie": {
                "type": "object",
                "required": ["veggieName", "veggieLike"],
                "properties": {
                    "veggieName": {
                        "type": "string",
                        "description": "The name of the vegetable.",
                    },
                    "veggieLike": {
                        "type": "boolean",
                        "description": "Do I like this vegetable?",
                    },
                },
            }
        }
    }
    oai = spec(response_schema=schema, components=components)
    res = faker.process(
        "/",
        OpenAPISpecification(source="default",
                             api=oai,
                             definitions=make_definitions_from_spec(oai)),
        request,
    )

    schema["components"] = components
    assert valid_schema(res.bodyAsJson, schema)
Exemple #9
0
def test_sateless_faker_5(mock_data_store):
    faker = StatefulFaker(mock_data_store)

    request = RequestBuilder.from_dict(
        dict(method="get", protocol="http", path="/", host="api.com")
    )

    schema = {"type": "array"}
    res = faker.process(
        OpenAPISpecification(source="default", api=spec(response_schema=schema)),
        request,
    )

    assert valid_schema(res.bodyAsJson, schema)
Exemple #10
0
def test_storage(mock_data_store, http_client, base_url):
    schema = {"$ref": "#/components/schemas/item"}

    components = {
        "schemas": {
            "item": {
                "type": "object",
                "required": ["foo", "baz"],
                "x-hmt-id-path": "itemId",
                "properties": {
                    "foo": {"type": "number"},
                    "bar": {"type": "string"},
                    "itemId": {"type": "string"},
                },
            }
        }
    }

    spec = spec_dict(
        path="/items/{id}", response_schema=schema, components=components, method="get"
    )
    spec["paths"]["/items/{id}"]["x-hmt-entity"] = "item"
    spec["paths"]["/items/{id}"]["get"]["x-hmt-operation"] = "read"
    spec["x-hmt-data"] = {"item": [{"foo": 10, "bar": "val", "itemId": "id123"}]}
    spec = convert_to_OpenAPIObject(spec)

    mock_data_store.add_mock(OpenAPISpecification(spec, "items"))

    req = HTTPRequest(base_url + "/admin/storage", method="DELETE")
    response = yield http_client.fetch(req)
    assert response.code == 200

    assert 0 == len(mock_data_store["items"].item)

    req = HTTPRequest(base_url + "/admin/storage/reset", method="POST", body="")
    response = yield http_client.fetch(req)
    assert response.code == 200

    assert 1 == len(mock_data_store["items"].item)

    with pytest.raises(HTTPClientError):
        req = HTTPRequest(base_url + "/admin/storage/reset", method="DELETE")
        response = yield http_client.fetch(req)

    assert 1 == len(mock_data_store["items"].item)
Exemple #11
0
def test_faker_5():
    faker = StatelessFaker()

    request = RequestBuilder.from_dict(
        dict(method="get", protocol="http", path="/", host="api.com")
    )

    schema = {"type": "array"}
    res = faker.process(
        "/",
        OpenAPISpecification(
            source="default",
            api=spec(response_schema=schema),
            definitions={"definitions": {}},
        ),
        request,
    )

    assert valid_schema(res.bodyAsJson, schema)
Exemple #12
0
    def spew(
        self, request: Request, specs: Sequence[OpenAPISpecification]
    ) -> Sequence[OpenAPISpecification]:
        if len(self._endpoints) == 0:
            return specs

        req = HttpExchangeWriter.to_dict(request)
        cs = {spec.source: convert_from_openapi(spec.api) for spec in specs}
        for endpoint in self._endpoints:
            res = requests.post(endpoint, json={"request": req, "schemas": cs})
            cs = res.json()

        out = [
            OpenAPISpecification(convert_to_openapi(dict_spec), name)
            for name, dict_spec in cs.items()
        ]

        for spec in out:
            self._mock_data_store.add_mock(spec)

        return out
Exemple #13
0
def test_insert(mock_data_store):
    faker = StatefulFaker(mock_data_store)

    request_schema = {
        "type": "object",
        "properties": {"item": {"$ref": "#/components/schemas/item"}},
    }

    response_schema = {"$ref": "#/components/schemas/item"}

    components = {
        "schemas": {
            "item": {
                "type": "object",
                "required": ["foo"],
                "x-hmt-id-path": "itemId",
                "properties": {
                    "foo": {"type": "number"},
                    "bar": {"type": "string"},
                    "baz": {"type": "string"},
                    "itemId": {"type": "string"},
                },
            }
        }
    }

    spec = spec_dict(
        path="/items",
        request_schema=request_schema,
        response_schema=response_schema,
        components=components,
        method="post",
    )
    spec["paths"]["/items"]["x-hmt-entity"] = "item"
    spec["paths"]["/items"]["post"]["x-hmt-operation"] = "insert"

    spec = convert_to_OpenAPIObject(spec)
    mock_data_store.add_mock(OpenAPISpecification(spec, "default"))

    schema = response_schema
    schema["components"] = components
    spec = OpenAPISpecification(source="default", api=spec)

    request = RequestBuilder.from_dict(
        dict(
            method="post",
            protocol="http",
            path="/items",
            host="api.com",
            bodyAsJson={"item": {"foo": 10, "bar": "val"}},
        )
    )
    res = faker.process(spec, request)

    assert valid_schema(res.bodyAsJson, schema)
    assert res.bodyAsJson["itemId"] is not None
    assert 10 == res.bodyAsJson["foo"]

    assert 1 == len(mock_data_store["default"].item)
    assert "val" == mock_data_store["default"].item[res.bodyAsJson["itemId"]]["bar"]

    request = RequestBuilder.from_dict(
        dict(
            method="post",
            protocol="http",
            path="/items",
            host="api.com",
            bodyAsJson={"item": {"foo": 20, "bar": "val1", "itemId": "id123"}},
        )
    )
    res = faker.process(spec, request)

    assert valid_schema(res.bodyAsJson, schema)
    assert "id123" == res.bodyAsJson["itemId"]
    assert 20 == res.bodyAsJson["foo"]

    assert 2 == len(mock_data_store["default"].item)
    assert "val1" == mock_data_store["default"].item[res.bodyAsJson["itemId"]]["bar"]

    request = RequestBuilder.from_dict(
        dict(
            method="post",
            protocol="http",
            path="/items",
            host="api.com",
            bodyAsJson={"item": {"foo": 30, "itemId": "id123"}},
        )
    )
    res = faker.process(spec, request)

    assert 2 == len(mock_data_store["default"].item)
    assert "bar" not in mock_data_store["default"].item[res.bodyAsJson["itemId"]]
    assert 30 == mock_data_store["default"].item[res.bodyAsJson["itemId"]]["foo"]
Exemple #14
0
 OpenAPISpecification(
     convert_to_openapi({
         "openapi": "",
         "servers": [{
             "url": "api.foo.com"
         }],  # we omit the protocol and it should still match
         "info": {
             "title": "",
             "version": ""
         },
         "paths": {
             "/user": {
                 "get": {
                     "responses": {
                         "200": {
                             "description": "userget"
                         }
                     }
                 },
                 "post": {
                     "responses": {
                         "200": {
                             "description": "userpost"
                         }
                     }
                 },
                 "description": "",
             },
             "/user/{id}": {
                 "parameters": [
                     {
                         "name": "id",
                         "in": "path",
                         "required": True,
                         "schema": {
                             "type": "integer"
                         },
                     },
                 ],
                 "get": {
                     "responses": {
                         "200": {
                             "description": "useridget"
                         }
                     }
                 },
                 "post": {
                     "responses": {
                         "201": {
                             "description": "useridpost"
                         }
                     }
                 },
             },
             "/user/{id}/name": {
                 "get": {
                     "responses": {
                         "200": {
                             "description": "useridnameget"
                         }
                     }
                 },
                 "post": {
                     "responses": {
                         "201": {
                             "description": "useridnamepost"
                         }
                     }
                 },
                 "description": "",
             },
         },
     }),
     "foo",
     {"definitions": {}},
 ),