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

Commit

Permalink
Implement strategy to use unique validations
Browse files Browse the repository at this point in the history
  • Loading branch information
NickSchimek committed Oct 18, 2021
1 parent beb4451 commit fd75923
Show file tree
Hide file tree
Showing 5 changed files with 20 additions and 4 deletions.
6 changes: 6 additions & 0 deletions models/base_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ class BaseModel(db.Model):
db.DateTime, onupdate=datetime.utcnow, default=datetime.utcnow, nullable=False
)

def validation_context(self):
return {}

@classmethod
def find(cls, id):
return cls.query.get_or_404(id, f"{cls._name()} not found")
Expand All @@ -32,6 +35,9 @@ def create(cls, schema, payload):
return obj

def update(self, schema, payload, context=None):
if not context:
context = self.validation_context()

attrs = self.validate(schema, payload, context=context, partial=True)

for k, v in attrs.items():
Expand Down
3 changes: 3 additions & 0 deletions models/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ def password(self, plaintext_password):
bcrypt.gensalt(current_app.config["WORK_FACTOR"]),
)

def validation_context(self):
return {"email": self.email}

def update_last_active(self):
self.lastActive = datetime.utcnow()
db.session.commit()
Expand Down
7 changes: 5 additions & 2 deletions schemas/user.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from ma import ma
from models.user import UserModel, RoleEnum
from marshmallow import fields, validates, ValidationError

from models.user import UserModel, RoleEnum


class UserSchema(ma.SQLAlchemyAutoSchema):
class Meta:
Expand All @@ -12,7 +13,9 @@ class Meta:

@validates("email")
def validate_uniqueness_of_email(self, value):
if UserModel.find_by_email(value):
if self.context.get("email") == value:
return
elif UserModel.find_by_email(value):
raise ValidationError(f"A user with email '{value}' already exists")

def get_role_value(self, obj):
Expand Down
4 changes: 3 additions & 1 deletion tests/integration/test_users.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,9 @@ def test_role_update(self, valid_header, create_unauthorized_user):
payload = {"role": RoleEnum.ADMIN.value}
self.client.patch(f"api/user/{id}", json=payload, headers=valid_header)

assert Admin.find(id).role == RoleEnum.ADMIN
user = Admin.find(id)
assert user.role == RoleEnum.ADMIN
assert user.type == "admin"


@pytest.mark.usefixtures("client_class", "empty_test_db")
Expand Down
4 changes: 3 additions & 1 deletion tests/unit/base_interface_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@ def test_update(self, mock_session):
with patch.object(self.object, "validate", return_value={}) as mock_validate:
response = self.object.update(schema=self.schema, payload={})

mock_validate.assert_called_with(self.schema, {}, context=None, partial=True)
mock_validate.assert_called_with(
self.schema, {}, context=self.object.validation_context(), partial=True
)
mock_session.add.assert_called_with(self.object)
mock_session.commit.assert_called()

Expand Down

0 comments on commit fd75923

Please sign in to comment.