Repository: sanic-org/sanic-ext (python)

Issue:
[Bug] Not all arguments are populated when validating multiple arguments
**Describe the bug**
Validating multiple sources of data as defined in the docs will not pass the data into the wrapped function as expected.
https://sanic.dev/en/plugins/sanic-ext/validation.html#what-can-be-validated

Also not possible to use all 3 fields as suggested in the example because of https://github.com/sanic-org/sanic-ext/blob/b65cd9f28c8d1e6ee0aad91685bfb84fc4925ac6/sanic_ext/extras/validation/decorator.py#L31

**To Reproduce**
```
@dataclass
class ModelA:
  a: str

@dataclass
class ModelB:
  b: str

@api.post('/test')
@validate(json=ModelA, query=ModelB)
async def test(req, json: ModelA, query: ModelB):
  return response.json({
    "json": asdict(json),
    "query": asdict(query),
  })
```

Results in 
```
curl -X 'POST' 'localhost:8000/api/test?b=B' -d '{"a": ""}'
{"description":"Internal Server Error","status":500,"message":"test() missing 1 required positional argument: 'query'","path":"/api/test","args":{},"exceptions":[{"type":"TypeError","exception":"test() missing 1 required positional argument: 'query'","frames":[{"file":".../my_app.py","line":925,"name":"handle_request","src":"response = await response"},{"file":".../site-packages/sanic_ext/extras/validation/decorator.py","line":77,"name":"decorated_function","src":"retval = f(*args, **kwargs)"}]}]}
```

**Expected behavior**
All fields that are validated were expected to be passed into the wrapped handler.

**Environment (please complete the following information):**
 - OS: Ubuntu
 - Browser chrome
 - Version 22.6.2

**Additional context**
I believe the `elif`s here should be `ifs`
https://github.com/sanic-org/sanic-ext/blob/b65cd9f28c8d1e6ee0aad91685bfb84fc4925ac6/sanic_ext/extras/validation/decorator.py#L55
```
curl -X 'POST' 'localhost:8000/api/test?b=B' -d '{"a": ""}'
{"json":{"a":""},"query":{"b":"B"}}
```

Pull request:
Both body and query validation
Closes #110 

Patch:
diff --git a/sanic_ext/extras/validation/decorator.py b/sanic_ext/extras/validation/decorator.py
index 093a295..de813db 100644
--- a/sanic_ext/extras/validation/decorator.py
+++ b/sanic_ext/extras/validation/decorator.py
@@ -59,7 +59,7 @@ def validate(
                     allow_multiple=True,
                     allow_coerce=True,
                 )
-            elif schemas["query"]:
+            if schemas["query"]:
                 await do_validation(
                     model=query,
                     data=request.args,


Test patch:
diff --git a/tests/extra/test_validation_multiple.py b/tests/extra/test_validation_multiple.py
new file mode 100644
index 0000000..b983b8b
--- /dev/null
+++ b/tests/extra/test_validation_multiple.py
@@ -0,0 +1,42 @@
+from dataclasses import asdict, dataclass
+
+from sanic import Sanic, json
+
+from sanic_ext.extras.validation.decorator import validate
+
+
+@dataclass
+class ModelA:
+    a: str
+
+
+@dataclass
+class ModelB:
+    b: str
+
+
+def test_both_body_and_query(app: Sanic):
+    @app.post("")
+    @validate(json=ModelA, query=ModelB)
+    async def test(_, body: ModelA, query: ModelB):
+        return json(
+            {
+                "body": asdict(body),
+                "query": asdict(query),
+            }
+        )
+
+    _, response = app.test_client.post("")
+    assert response.status == 400
+
+    _, response = app.test_client.post("", params={"b": "bbb"})
+    assert response.status == 400
+
+    _, response = app.test_client.post(
+        "", params={"b": "bbb"}, json={"a": "aaa"}
+    )
+    assert response.status == 200
+    assert response.json == {
+        "body": {"a": "aaa"},
+        "query": {"b": "bbb"},
+    }