예제 #1
0
def test_custom_validation():
    def optional(t):
        def do(elem):
            if elem is None:
                return elem
            return Type(elem)

        return do

    types = {
        "articles": {
            "title": optional(str),
        },
    }
    response = {
        "data": {
            "type": "articles",
            "id": "1",
            "attributes": {
                "title": None
            },
        },
    }
    validator = Validator(top="articles", types=types)
    result = validator.validate(response)
    assert result["data"]["title"] is None
예제 #2
0
def test_include_args():
    types = {
        "articles": {
            "author": Rel("people"),
            "comments": Rel(["comments"])
        },
        "people": {
            "articles": Rel(["articles"]),
            "comments": Rel(["comments"]),
        },
        "comments": {
            "author": Rel("people")
        }
    }

    include = {
        "author": {
            "articles": {},
            "comments": {},
        },
        "comments": {}
    }

    validator = Validator("articles", types, include=include)

    args = validator.include_args()
    assert set(args) == {"author", "author.articles", "author.comments",
                         "comments"}
예제 #3
0
def test_include_null_field():
    types = {
        "articles": {
            "author": Rel("people"),
        },
        "people": {
            "foo": Type(str),
        },
    }
    include = {
        "author": {},
    }

    response = {
        "data": {
            "type": "articles",
            "id": "1",
            "relationships": {
                "author": {
                    "links": "foobar",
                    "data": None
                },
            },
        }
    }
    validator = Validator("articles", types, include=include)
    msg = validator.validate(deepcopy(response))
    assert msg["data"]["author"]["data"] is None
예제 #4
0
def test_include_field_without_data():
    types = {
        "articles": {
            "author": Rel("people"),
        },
        "people": {
            "foo": Type(str),
        },
    }
    include = {
        "author": {},
    }

    response = {
        "data": {
            "type": "articles",
            "id": "1",
            "relationships": {
                "author": {
                    "links": "foobar"
                },
            },
        }
    }
    validator = Validator("articles", types)
    validator.validate(deepcopy(response))

    validator = Validator("articles", types, include=include)
    with pytest.raises(ValidationError):
        validator.validate(deepcopy(response))
예제 #5
0
def test_bad_rel_list_type():
    types = {
        "articles": {
            "comments": Rel(["bar"]),
        },
        "foo": {},
        "bar": {},
    }
    correct_types = {
        "articles": {
            "comments": Rel(["foo"]),
        },
        "foo": {},
        "bar": {},
    }
    response = {
        "data": {
            "type": "articles",
            "id": "1",
            "relationships": {
                "comments": {
                    "data": [{
                        "id": "1",
                        "type": "foo",
                    }]
                }
            },
        },
    }
    validator = Validator(top="articles", types=types)
    with pytest.raises(ValidationError):
        validator.validate(response)
    validator = Validator(top="articles", types=correct_types)
    validator.validate(response)
예제 #6
0
def test_bad_field_type():
    types = {
        "articles": {
            "title": Type(str),
        },
    }
    response1 = {
        "data": {
            "type": "articles",
            "id": "1",
            "attributes": {
                "title": ["Hello", "world"]
            },
        },
    }
    validator = Validator(top="articles", types=types)
    with pytest.raises(ValidationError):
        validator.validate(response1)

    response2 = {
        "data": {
            "type": "articles",
            "id": "1",
            "attributes": {
                "title": None
            },
        },
    }
    validator = Validator(top="articles", types=types)
    with pytest.raises(ValidationError):
        validator.validate(response2)
예제 #7
0
def test_all_is_well():
    validator = Validator(top=["articles"], types=types, include=include)
    mcopy = deepcopy(response)

    mcopy = validator.validate(mcopy)

    author_obj = mcopy["data"][0]

    assert author_obj["title"] == author_obj[".attributes"]["title"]
    assert author_obj["author"] == author_obj[".relationships"]["author"]
    assert author_obj["comments"] == author_obj[".relationships"]["comments"]

    assert author_obj["author"]["data"]["firstName"] == "Dan"
    assert author_obj["comments"]["data"][0]["body"] == "First!"

    assert mcopy["links"] == response["links"]
예제 #8
0
def test_fields_args():
    types = {
        "articles": {
            "title": Type(str),
            "comments": Rel(["comments"])
        },
        "comments": {
            "foo": Type(str),
            "bar": Type(str),
        }
    }
    fields = {"articles": ["comments"], "comments": ["foo", "bar"]}
    validator = Validator(top="foo", types=types, fields=fields)
    attrs = validator.fields_args()
    assert set(attrs) == {
        "fields[articles]=comments", "fields[comments]=foo,bar"
    }
예제 #9
0
def test_fields_missing_field():
    types = {
        "articles": {
            "title": Type(str),
            "body": Type(str),
        },
    }
    response = {
        "data": {
            "type": "articles",
            "id": "1",
            "attributes": {
                "body": "JSON:API paints my bikeshed!"
            },
        },
    }

    fields = {"articles": ["title"]}

    validator = Validator(top="articles", types=types, fields=fields)
    with pytest.raises(ValidationError):
        validator.validate(response)
예제 #10
0
def test_rel_fields():
    types = {
        "articles": {
            "title": Type(str),
            "comments": Rel(["comments"])
        },
        "comments": {
            "foo": Type(str),
            "bar": Type(str),
        }
    }
    response = {
        "data": {
            "type": "articles",
            "id": "1",
            "relationships": {
                "comments": {
                    "data": [{
                        "id": "1",
                        "type": "comments",
                    }]
                }
            },
        },
        "included": [{
            "type": "comments",
            "id": "1",
            "attributes": {
                "foo": "baz"
            }
        }]
    }

    fields = {"articles": ["comments"], "comments": ["foo"]}

    validator = Validator(top="articles", types=types, fields=fields)
    res = validator.validate(response)
    assert res["data"]["comments"]["data"][0]["foo"] == "baz"
예제 #11
0
def test_fields_work():
    types = {
        "articles": {
            "title": Type(str),
            "body": Type(str),
        },
    }
    response = {
        "data": {
            "type": "articles",
            "id": "1",
            "attributes": {
                "title": "JSON:API paints my bikeshed!"
            },
        },
    }

    fields = {"articles": ["title"]}

    validator = Validator(top="articles", types=types, fields=fields)
    res = validator.validate(response)

    assert "title" in res["data"]
예제 #12
0
def test_null_relation():
    types = {
        "articles": {
            "comments": Rel("bar"),
        },
        "foo": {},
        "bar": {},
    }
    response = {
        "data": {
            "type": "articles",
            "id": "1",
            "relationships": {
                "comments": {
                    "data": None
                }
            },
        },
    }
    validator = Validator("articles", types)
    msg = validator.validate(response)

    assert msg["data"]["comments"]["data"] is None
예제 #13
0
def test_relation_without_data():
    types = {
        "articles": {
            "comments": Rel(["bar"]),
        },
        "foo": {},
        "bar": {},
    }
    response = {
        "data": {
            "type": "articles",
            "id": "1",
            "relationships": {
                "comments": {
                    "links": "http://foo.bar"
                }
            },
        },
    }
    validator = Validator("articles", types)
    msg = validator.validate(response)

    assert "links" in msg["data"]["comments"]
    assert "data" not in msg["data"]["comments"]
예제 #14
0
def test_missing_type():
    types = {
        "articles": {
            "title": Type(str),
        },
    }
    response = {
        "data": {
            "type": "articles",
            "id": "1",
            "attributes": {
                "title": "JSON:API paints my bikeshed!"
            },
        },
        "included": [{
            "type": "things",
            "id": "1",
        }]
    }

    validator = Validator(top="articles", types=types)
    with pytest.raises(ValidationError):
        validator.validate(response)

    other_types = {"things": {}}

    validator = Validator(top="articles", types=other_types)
    with pytest.raises(ValidationError):
        validator.validate(response)

    full_types = {
        "articles": {
            "title": Type(str),
        },
        "things": {}
    }

    validator = Validator(top="articles", types=full_types)
    validator.validate(response)
예제 #15
0
def test_missing_fields():
    types = {
        "articles": {
            "title": Type(str),
        },
    }
    response1 = {
        "data": {
            "type": "articles",
            "id": "1",
            "attributes": {},
        },
    }
    validator = Validator(top="articles", types=types)
    with pytest.raises(ValidationError):
        validator.validate(response1)

    response2 = {
        "data": {
            "type": "articles",
            "id": "1",
        },
    }
    validator = Validator(top="articles", types=types)
    with pytest.raises(ValidationError):
        validator.validate(response2)

    types_rel = {"articles": {"comments": Rel("comments")}, "comments": {}}

    response1_rel = {
        "data": {
            "type": "articles",
            "id": "1",
        },
    }
    validator = Validator(top="articles", types=types_rel)
    with pytest.raises(ValidationError):
        validator.validate(response1_rel)

    response2_rel = {
        "data": {
            "type": "articles",
            "id": "1",
            "relationships": {
                "things": {
                    "data": {
                        "type": "comments",
                        "id": "1"
                    }
                }
            }
        },
    }
    validator = Validator(top="articles", types=types_rel)
    with pytest.raises(ValidationError):
        validator.validate(response2_rel)
예제 #16
0
def test_bad_top_type():
    types = {
        "articles": {
            "title": Type(str),
        },
        "people": {
            "firstName": Type(str),
        }
    }
    response = {
        "data": {
            "type": "articles",
            "id": "1",
            "attributes": {
                "title": "JSON:API paints my bikeshed!"
            },
        },
    }

    validator = Validator(top="people", types=types)
    with pytest.raises(ValidationError):
        validator.validate(response)

    validator = Validator(top=["people"], types=types)
    with pytest.raises(ValidationError):
        validator.validate(response)

    validator = Validator(top=["articles"], types=types)
    with pytest.raises(ValidationError):
        validator.validate(response)

    validator = Validator(top="articles", types=types)
    validator.validate(response)

    response2 = {
        "data": [{
            "type": "articles",
            "id": "1",
            "attributes": {
                "title": "JSON:API paints my bikeshed!"
            },
        }],
    }
    validator = Validator(top="articles", types=types)
    with pytest.raises(ValidationError):
        validator.validate(response2)
    validator = Validator(top=["people"], types=types)
    with pytest.raises(ValidationError):
        validator.validate(response2)
예제 #17
0
def test_missing_includes():
    types = {
        "articles": {
            "author": Rel("people"),
            "comments": Rel(["comments"])
        },
        "people": {
            "foo": Type(str),
        },
        "comments": {
            "foo": Type(str),
        }
    }
    include = {
        "author": {},
        "comments": {},
    }

    response_data = {
        "type": "articles",
        "id": "1",
        "relationships": {
            "author": {
                "data": {
                    "id": "1",
                    "type": "people",
                }
            },
            "comments": {
                "data": [{
                    "id": "1",
                    "type": "comments",
                }]
            }
        },
    }
    response_1 = {
        "data": response_data,
        "included": [{
            "id": "1",
            "type": "comments",
            "attributes": {
                "foo": "bar"
            }
        }]
    }
    response_2 = {
        "data": response_data,
        "included": [{
            "id": "1",
            "type": "people",
            "attributes": {
                "foo": "bar"
            }
        }]
    }
    response_3 = {
        "data": response_data,
        "included": [
            {
                "id": "1",
                "type": "people",
                "attributes": {
                    "foo": "bar"
                }
            },
            {
                "id": "1",
                "type": "comments",
                "attributes": {
                    "foo": "bar"
                }
            }
        ]
    }

    validator = Validator("articles", types, include=include)
    with pytest.raises(ValidationError):
        validator.validate(deepcopy(response_1))
    with pytest.raises(ValidationError):
        validator.validate(deepcopy(response_2))
    validator.validate(deepcopy(response_3))