-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
A third batch of Pydantic validation for rest/client/account.py #13736
Changes from 10 commits
f39bfc5
b854c09
cdeb0a3
92f7f01
e584fa0
76d615e
3defe6f
35d664a
8143310
38ae8c7
a840e8c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Improve validation of request bodies for the following client-server API endpoints: [`/account/3pid/add`](https://spec.matrix.org/v1.3/client-server-api/#post_matrixclientv3account3pidadd), [`/account/3pid/bind`](https://spec.matrix.org/v1.3/client-server-api/#post_matrixclientv3account3pidbind), [`/account/3pid/delete`](https://spec.matrix.org/v1.3/client-server-api/#post_matrixclientv3account3piddelete) and [`/account/3pid/unbind`](https://spec.matrix.org/v1.3/client-server-api/#post_matrixclientv3account3pidunbind). |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,14 +11,37 @@ | |
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
import unittest | ||
import unittest as stdlib_unittest | ||
|
||
from pydantic import ValidationError | ||
from pydantic import BaseModel, ValidationError | ||
from typing_extensions import Literal | ||
|
||
from synapse.rest.client.models import EmailRequestTokenBody | ||
|
||
|
||
class EmailRequestTokenBodyTestCase(unittest.TestCase): | ||
class ThreepidMediumEnumTestCase(stdlib_unittest.TestCase): | ||
class Model(BaseModel): | ||
medium: Literal["email", "msisdn"] | ||
|
||
def test_accepts_valid_medium_string(self) -> None: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wonder if we should roll our own There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note that 3.11 will have a StrEnum in the stdlib: https://docs.python.org/3.11/library/enum.html?highlight=strenum#enum.StrEnum There's a backport here. If we do this I'd prefer to import from stdlib and fallback to the backport. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. absolutely fine with that idea, as long as we have confidence that the usual pitfall around |
||
"""Sanity check that Pydantic behaves sensibly with an enum-of-str | ||
|
||
This is arguably more of a test of a class that inherits from str and Enum | ||
simultaneously. | ||
""" | ||
model = self.Model.parse_obj({"medium": "email"}) | ||
self.assertEqual(model.medium, "email") | ||
|
||
def test_rejects_invalid_medium_value(self) -> None: | ||
with self.assertRaises(ValidationError): | ||
self.Model.parse_obj({"medium": "interpretive_dance"}) | ||
|
||
def test_rejects_invalid_medium_type(self) -> None: | ||
with self.assertRaises(ValidationError): | ||
self.Model.parse_obj({"medium": 123}) | ||
|
||
|
||
class EmailRequestTokenBodyTestCase(stdlib_unittest.TestCase): | ||
base_request = { | ||
"client_secret": "hunter2", | ||
"email": "alice@wonderland.com", | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tiny tiny question: would calling this
ClientSecretStr
make more sense so that the class is more readable without looking up the definition of this? I don't think it matters either way but it may be a good convention to have, in which case we would better consider that nowThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea, I like it. So what's the rule of thumb: if you need an alias for a
constr
,conint
orconfloat
, call itSomethingSomethingStr
,FooBarInt
orPotatoFloat
rather thanBlahBlahType
?Perhaps you'd also like to see this for
conlist
(JSON arrays) and certain mapping types too?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, sounds good to me; I wouldn't do it for pydantic models though, so you wouldn't call e.g.
PostBody
PostBodyMap
.