Skip to content
This repository was archived by the owner on Dec 19, 2021. It is now read-only.

Commit e33935b

Browse files
committed
Implement strategy to use unique validations
1 parent beb4451 commit e33935b

File tree

4 files changed

+22
-4
lines changed

4 files changed

+22
-4
lines changed

models/base_model.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ def create(cls, schema, payload):
3232
return obj
3333

3434
def update(self, schema, payload, context=None):
35+
if not context:
36+
context = {}
37+
38+
context["obj"] = self
3539
attrs = self.validate(schema, payload, context=context, partial=True)
3640

3741
for k, v in attrs.items():

schemas/user.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
from ma import ma
2-
from models.user import UserModel, RoleEnum
2+
from sqlalchemy import inspect
33
from marshmallow import fields, validates, ValidationError
44

5+
from models.user import UserModel, RoleEnum
6+
57

68
class UserSchema(ma.SQLAlchemyAutoSchema):
79
class Meta:
@@ -12,7 +14,14 @@ class Meta:
1214

1315
@validates("email")
1416
def validate_uniqueness_of_email(self, value):
15-
if UserModel.find_by_email(value):
17+
obj = self.context.get("obj")
18+
if obj:
19+
obj.email = value
20+
if inspect(
21+
obj
22+
).attrs.email.history.has_changes() and UserModel.find_by_email(value):
23+
raise ValidationError(f"A user with email '{value}' already exists")
24+
elif UserModel.find_by_email(value):
1625
raise ValidationError(f"A user with email '{value}' already exists")
1726

1827
def get_role_value(self, obj):

tests/integration/test_users.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import pytest
22
from unittest.mock import patch
3+
from db import db
34
from models.user import UserModel
45
from models.users.admin import Admin
56
from schemas import UserRegisterSchema
@@ -132,7 +133,10 @@ def test_role_update(self, valid_header, create_unauthorized_user):
132133
payload = {"role": RoleEnum.ADMIN.value}
133134
self.client.patch(f"api/user/{id}", json=payload, headers=valid_header)
134135

135-
assert Admin.find(id).role == RoleEnum.ADMIN
136+
db.session.rollback()
137+
user = UserModel.find(id)
138+
assert user.role == RoleEnum.ADMIN
139+
assert user.type == "admin"
136140

137141

138142
@pytest.mark.usefixtures("client_class", "empty_test_db")

tests/unit/base_interface_test.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ def test_update(self, mock_session):
5959
with patch.object(self.object, "validate", return_value={}) as mock_validate:
6060
response = self.object.update(schema=self.schema, payload={})
6161

62-
mock_validate.assert_called_with(self.schema, {}, context=None, partial=True)
62+
context = {"obj": self.object}
63+
mock_validate.assert_called_with(self.schema, {}, context=context, partial=True)
6364
mock_session.add.assert_called_with(self.object)
6465
mock_session.commit.assert_called()
6566

0 commit comments

Comments
 (0)