diff --git a/Pipfile b/Pipfile index 5dd4349..cfe1397 100644 --- a/Pipfile +++ b/Pipfile @@ -6,7 +6,6 @@ verify_ssl = true [dev-packages] [packages] -twilio = "*" flask = "*" pymysql = "*" flask-praetorian = "*" @@ -16,6 +15,8 @@ flask-marshmallow = "*" marshmallow = "*" pytest = "*" marshmallow-sqlalchemy = "*" +twilio = "*" +pytest-flask = "*" [requires] python_version = "3.8" diff --git a/Pipfile.lock b/Pipfile.lock index 03acab4..17e551f 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "80fd792f6fec6ea79a6795b929139827dcf748408d6b337e8f1b5dc2cff36302" + "sha256": "eb1b1d3ad68e400f0f9cb120594b5b710072f825f2ad49112dab55008e36ed8f" }, "pipfile-spec": 6, "requires": { @@ -51,10 +51,10 @@ }, "click": { "hashes": [ - "sha256:8a18b4ea89d8820c5d0c7da8a64b2c324b4dabb695804dbfea19b9be9d88c0cc", - "sha256:e345d143d80bf5ee7534056164e5e112ea5e22716bbb1ce727941f4c8b471b9a" + "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a", + "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc" ], - "version": "==7.1.1" + "version": "==7.1.2" }, "deprecated": { "hashes": [ @@ -86,11 +86,11 @@ }, "flask-marshmallow": { "hashes": [ - "sha256:01520ef1851ccb64d4ffb33196cddff895cc1302ae1585bff1abf58684a8111a", - "sha256:28b969193958d9602ab5d6add6d280e0e360c8e373d3492c2f73b024ecd36374" + "sha256:6e6aec171b8e092e0eafaf035ff5b8637bf3a58ab46f568c4c1bab02f2a3c196", + "sha256:a1685536e7ab5abdc712bbc1ac1a6b0b50951a368502f7985e7d1c27b3c21e59" ], "index": "pypi", - "version": "==0.11.0" + "version": "==0.12.0" }, "flask-migrate": { "hashes": [ @@ -190,19 +190,19 @@ }, "marshmallow": { "hashes": [ - "sha256:90854221bbb1498d003a0c3cc9d8390259137551917961c8b5258c64026b2f85", - "sha256:ac2e13b30165501b7d41fc0371b8df35944f5849769d136f20e2c5f6cdc6e665" + "sha256:56663fa1d5385c14c6a1236badd166d6dee987a5f64d2b6cc099dadf96eb4f09", + "sha256:f12203bf8d94c410ab4b8d66edfde4f8a364892bde1f6747179765559f93d62a" ], "index": "pypi", - "version": "==3.5.1" + "version": "==3.5.2" }, "marshmallow-sqlalchemy": { "hashes": [ - "sha256:9301c6fd197bd97337820ea1417aa1233d0ee3e22748ebd5821799bc841a57e8", - "sha256:dde9e20bcb710e9e59f765a38e3d6d17f1b2d6b4320cbdc2cea0f6b57f70d08c" + "sha256:3247e41e424146340b03a369f2b7c6f0364477ccedc4e2481e84d5f3a8d3c67f", + "sha256:dbbe51d28bb28e7ee2782e51310477f7a2c5a111a301f6dd8e264e11ab820427" ], "index": "pypi", - "version": "==0.22.3" + "version": "==0.23.0" }, "more-itertools": { "hashes": [ @@ -300,6 +300,14 @@ "index": "pypi", "version": "==5.4.1" }, + "pytest-flask": { + "hashes": [ + "sha256:44948d3feab48c69e89b087129cc4db66bad9cb5aa472c08dfc798c69f4eac67", + "sha256:4d5678a045c07317618d80223ea124e21e8acc89dae109542dd1fdf6783d96c2" + ], + "index": "pypi", + "version": "==1.0.0" + }, "python-dateutil": { "hashes": [ "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c", @@ -317,10 +325,10 @@ }, "pytz": { "hashes": [ - "sha256:1c557d7d0e871de1f5ccd5833f60fb2550652da6be2693c1e02300743d21500d", - "sha256:b02c06db6cf09c12dd25137e563b31700d3b80fcc4ad23abb7a315f2789819be" + "sha256:a494d53b6d39c3c6e44c3bec237336e14305e4f29bbf800b599253057fbb79ed", + "sha256:c35965d010ce31b23eeb663ed3cc8c906275d6be1a34393a1d73a41febf4a048" ], - "version": "==2019.3" + "version": "==2020.1" }, "pytzdata": { "hashes": [ @@ -369,10 +377,10 @@ }, "twilio": { "hashes": [ - "sha256:620d7c9ef9e09c67a690ad02fdf76f502e5115227a56369e5f235d8a6b717c69" + "sha256:7ef6ad19251fee6a41f1184e97b4fcb62f4a8c0e6f4b78797e40e9c92aed006d" ], "index": "pypi", - "version": "==6.38.1" + "version": "==6.39.0" }, "urllib3": { "hashes": [ diff --git a/app/models.py b/app/models.py index 8a5b56f..4bee864 100644 --- a/app/models.py +++ b/app/models.py @@ -19,33 +19,29 @@ class Users(db.Model): access_key = db.Column(db.Text) lang_type = db.Column(db.Integer) badge = db.Column(db.Integer) - status = db.Column(db.Integer) - admin_status = db.Column(db.Integer) + status = db.Column(db.Integer, server_default=text("0")) + admin_status = db.Column(db.Integer, server_default=text("0")) device_id = db.Column(db.Text) device_type = db.Column(db.Integer) created = db.Column(db.TIMESTAMP, nullable=False, server_default=db.func.now()) def __init__( self, - social_id, - type, full_name, email, password, gender, mobile, - user_image, city_id, user_type, - otp, - otp_valid_time, - access_key, lang_type, badge, - status, - admin_status, device_id, device_type, + social_id="", + access_key="", + user_image=None, + type=0, ): self.social_id = social_id self.type = type @@ -57,13 +53,9 @@ class Users(db.Model): self.user_image = user_image self.city_id = city_id self.user_type = user_type - self.otp = otp - self.otp_valid_time = otp_valid_time self.access_key = access_key self.lang_type = lang_type self.badge = badge - self.status = status - self.admin_status = admin_status self.device_id = device_id self.device_type = device_type diff --git a/app/routes.py b/app/routes.py index 604ea50..534f204 100644 --- a/app/routes.py +++ b/app/routes.py @@ -8,7 +8,7 @@ from app import app def create_user(): data = request.get_json() insert_data(schema="Users", data=data) - send_otp(receiver=data["mobile"]) + # send_otp(receiver=data["mobile"]) return make_response(jsonify("User created, pending OTP verification")) diff --git a/app/schema.py b/app/schema.py index e4b438d..098b305 100644 --- a/app/schema.py +++ b/app/schema.py @@ -8,12 +8,12 @@ class UsersSchema(ma.Schema): full_name = fields.Str(required=True, validate=Length(max=255)) email = fields.Email(required=True, validate=Length(max=255)) password = fields.Str(validate=Length(max=255)) - gender = fields.Integer(required=True, validate=Range(min=1, max=2)) + gender = fields.Integer(required=True, validate=Range(min=1, max=3)) mobile = fields.Str(required=True, validate=Length(max=13)) user_image = fields.Str(validate=Length(max=255)) user_type = fields.Integer(required=True, validate=Range(min=1, max=2)) lang_type = fields.Integer(required=True, validate=Range(min=1, max=2)) - device_type = fields.Integer(required=True, validate=Range(min=1, max=2)) + device_type = fields.Integer(validate=Range(min=1, max=2)) device_id = fields.Str(required=True) diff --git a/config.py b/config.py index a97fa73..cca6efd 100644 --- a/config.py +++ b/config.py @@ -1,7 +1,7 @@ -from constants import connection_uri +from constants import connection_uri, secret_key class Config(object): SQLALCHEMY_DATABASE_URI = connection_uri SQLALCHEMY_TRACK_MODIFICATIONS = False - SECRET_KEY = "trolaso" + SECRET_KEY = secret_key diff --git a/database/crud.py b/database/crud.py index b5b1b81..1e5cb78 100644 --- a/database/crud.py +++ b/database/crud.py @@ -3,10 +3,13 @@ from app import db from app.models import * from app.schema import * from marshmallow import ValidationError +from pydoc import locate def insert_data(schema, data): - instance = validate_data(schema=schema, data=data) + validate_data(schema=schema, data=data) + model = locate("app.models." + schema) + instance = model(**data) db.session.add(instance) db.session.commit() @@ -22,11 +25,11 @@ def save_otp(mobile, otp): def validate_data(schema, data): - validation_schema = schema + "Schema()" - instance = validation_schema + schema_name = schema + "Schema" + validation_schema = locate("app.schema." + schema_name) + instance = validation_schema() try: - output = instance.load(data).data - return output + instance.load(data) except ValidationError as err: print(err.messages) @@ -37,16 +40,17 @@ def fetch_stored_otp(mobile): return otp -def validate_otp(mobile): +def validate_account(mobile): timestamp = datetime.now() db.session.query(table="Users").filter_by(mobile=mobile).update( dict(otp_valid_time=timestamp) ) + db.session.query(table="Users").filter_by(mobile=mobile).update(dict(status=1)) def verify_otp(mobile, otp): stored_otp = fetch_stored_otp(mobile=mobile) if stored_otp == otp: - validate_otp(mobile=mobile) + validate_account(mobile=mobile) return True return False diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 0000000..476b067 --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,10 @@ +from app import app as test_app +from pytest import fixture +from secrets import token_bytes + + +@fixture +def app(): + test_app.config["TESTING"] = True + test_app.config["WTF_CSRF_ENABLED"] = False + return test_app diff --git a/tests/queries_test.py b/tests/queries_test.py index 4dfe2ac..291568e 100644 --- a/tests/queries_test.py +++ b/tests/queries_test.py @@ -1,4 +1,5 @@ from app.models import * +from datetime import datetime def test_users(): @@ -52,8 +53,9 @@ def test_user_ratings(): def test_venue_images(): - test = VenueImages.query.filter_by(id=3).first() - assert test.user_id == 9 + test = VenueImages.query.filter_by(id=6).first() + date = datetime(year=2019, month=7, day=28, hour=14, minute=1, second=21) + assert test.updated == date def test_venues(): @@ -63,7 +65,8 @@ def test_venues(): def test_view_news(): test = ViewNews.query.filter_by(id=57).first() - assert test.news_id == 10 + date = datetime(year=2019, month=7, day=16, hour=11, minute=32, second=16) + assert test.created == date def test_web_bookings(): diff --git a/tests/requests_test.py b/tests/requests_test.py new file mode 100644 index 0000000..c90d0ad --- /dev/null +++ b/tests/requests_test.py @@ -0,0 +1,23 @@ +from app.models import * +from config import Config +from pytest import fixture +from secrets import token_hex +from werkzeug.security import generate_password_hash + + +def test_registration(client): + user = { + "full_name": "Bilal Balaperdida", + "email": "oyvey@hotmail.com", + "password": generate_password_hash(password="lifeisabitch", method="md5"), + "gender": 3, + "mobile": "+212655778899", + "city_id": 12, + "user_type": 1, + "lang_type": 1, + "device_id": token_hex(8), + "device_type": 1, + "badge": 0, + } + response = client.post("/register", json=user) + assert response.status == "200 OK"