Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[1061] Add resolver_match to the mocked request object in the Ninja's TestClient #1060

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

zigcccc
Copy link

@zigcccc zigcccc commented Jan 22, 2024

The problem

Previously, the Ninja's TestClient did not include the resolver_match in the mocked request object. That's causing issue when having the following setup:

# in schemas.py

class EntityUpdateSchema(Schema):
    id: int

    class Meta:
        exclude: ("id",)
        fields_optional = "__all__"
        model = Entity

    @staticmethod
    def resolve_id(obj, context):
        return context["request"].resolver_match.kwargs.get("id")

The above schema will infer the id property from the path. So, assuming you have the following path:

@router.patch("/entities/{id}/")
def patch_entity(request: HttpRequest, id: int, partial_entity_data: EntityUpdateSchema):
    ...

the EntityUpdateSchema will be populated with the id received from the path. I find this useful for when we need to do some validation against the object and we need to query the object that we're currently working with.

And the good news is - this works perfectly! When I call the endpoint, everything is behaving as it should :chef-kiss:

So, what's the problem?

When writing tests, though, and using the TestClient from Ninja, this is not working at all. Doing client.patch("/entities/123") will never populate the schema field, and we will get a validation error back, saying the id field is missing.

The solution

The solution for this is quite simple - when we build the mock request object, we need to set the resolver_match to the ninja resolver that we get back from the URL. By doing that, the schema is again able to infer the id and everything works as it should, even in tests.

While I could just create my own TestClient that would inherit from Ninja's test client, and override the _resolve method, I assume this would be beneficial to others as well. Hence, creating a PR with the fix in hopes that others will find it useful as well.

path: str,
data: Dict,
request_params: Any,
resolver_match: Any,
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this could probably be better typed, but honestly, since it's used internally and not exposed as the external testing client's API, I was personally fine with Any and be done with it.

@zigcccc zigcccc changed the title [testing] Add resolver_match to the mocked request object in the Ninja's TestClient [1061] Add resolver_match to the mocked request object in the Ninja's TestClient Jan 22, 2024
@zigcccc
Copy link
Author

zigcccc commented Jan 22, 2024

@vitalik any thoughts re this?:)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant