Skip to content

Commit

Permalink
Merge pull request #7 from yeboah326/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
yeboah326 committed Dec 10, 2021
2 parents d1e775b + 40e76ec commit cfcdd91
Show file tree
Hide file tree
Showing 12 changed files with 299 additions and 64 deletions.
17 changes: 16 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
# Project Setup

## Setup the database
**Create all tables in the database**

`docker-compose exec backend python3 run.py create_db`

**Accessing the database**
`docker-compose exec db psql --username={your_username} --dbname={your_dbname}`

## Access flask shell

`docker-compose exec backend flask shell`

## Running Tests
**Running a single test from a test file**

`docker-compose exec backend pytest api/tests/name_of_test_file.py::name_of_test -vv`
Expand All @@ -7,4 +22,4 @@
`docker-compose exec backend pytest api/tests/name_of_test_file.py -vv`

**Run all test files in a single directory**
`docker-compose exec backend pytest api/tests/ -vv`
`docker-compose exec backend pytest api/tests/ -vv`
10 changes: 7 additions & 3 deletions backend/api/auth/controllers.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
user_schema = UserSchema(dump_only=["id"], unknown="EXCLUDE")
users_schema = UserSchema(many=True, dump_only=["id"], unknown="EXCLUDE")


@auth.get("/hello")
def auth_hello():
return {"message": "Auth blueprint is working"}, 200
Expand All @@ -22,36 +23,39 @@ def auth_create_new_user():
new_user = user_schema.load(data)

# Set the password for the user
new_user.password = data['password']
new_user.password = data["password"]

# Save data to the database
db.session.add(new_user)
db.session.commit()

return {"message": f"New user {new_user.name} created"}, 200


@auth.post("/login")
def auth_login_user():
# Collect data from the json post body
data = request.json

# Check whether user with given email exists
user: User = User.find_by_email(data['email'])
user: User = User.find_by_email(data["email"])

if user:
password_correct = user.check_password(data['password'])
password_correct = user.check_password(data["password"])
if password_correct:
token = create_access_token(identity=user.id)
return {"token": token, "user_type": f"{user.type}"}, 200
return {"message": "Wrong user credentials"}, 400
return {"message": "A user with the given credentials does not exist"}, 404


@auth.get("/users")
@jwt_required()
def auth_get_all_users():
all_users = User.query.all()
return jsonify(users_schema.dump(all_users)), 200


@auth.get("/users/<id>")
@jwt_required()
def auth_get_user_by_id(id):
Expand Down
6 changes: 5 additions & 1 deletion backend/api/auth/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ class User(db.Model):
email = db.Column(db.String(50), nullable=False, unique=True)
password_hash = db.Column(db.String(120), nullable=False)
type = db.Column(db.String(10), nullable=False, default="normal")
contacts = db.relationship(
"Contact", backref="user", cascade="all, delete", passive_deletes=True
)

@property
def password(self):
Expand All @@ -21,7 +24,7 @@ def password(self, password) -> None:
self.password_hash = generate_password_hash(password)

def check_password(self, password) -> bool:
return check_password_hash(self.password_hash, password)\
return check_password_hash(self.password_hash, password)

@classmethod
def find_by_id(cls, id):
Expand All @@ -34,6 +37,7 @@ def find_by_email(cls, email):
def __repr__(self):
return f"<User | {self.name} | {self.email}>"


class UserSchema(Schema):
id = fields.Int(required=True)
name = fields.Str(required=True)
Expand Down
2 changes: 1 addition & 1 deletion backend/api/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

basedir = os.path.abspath(os.path.dirname(__file__))


class BaseConfig(object):
SQLALCHEMY_DATABASE_URI = os.getenv("DATABASE_URL", "sqlite://")
SQLALCHEMY_TRACK_MODIFICATIONS = False

96 changes: 94 additions & 2 deletions backend/api/reminder/controllers.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,99 @@
from flask import Blueprint
from flask import Blueprint, request, jsonify
from flask_jwt_extended import jwt_required, get_jwt_identity
from api import db
from api.reminder.models import Contact, ContactSchema
from marshmallow import ValidationError
from sqlalchemy import extract
import datetime

reminder = Blueprint("reminder", __name__, url_prefix="/api/reminder")

# contact schema
contact_schema = ContactSchema(unknown="EXCLUDE")
contacts_schema = ContactSchema(many=True, unknown="EXCLUDE")


@reminder.get("/hello")
def reminder_hello():
return {"message": "Reminder blueprint working"}
return {"message": "Reminder blueprint working"}


@reminder.post("/contact")
@jwt_required()
def reminder_create_contact():

# Retrieve the data
data = request.json

try:
# Create a new instance of the contact
new_contact = contact_schema.load(data)
new_contact.user_id = get_jwt_identity()

# Save the contact
db.session.add(new_contact)
db.session.commit()

return {"message": "Contact created successfully"}, 200

except ValidationError as err:
return {"message": "Bad data format"}, 400


@reminder.get("/contact")
@jwt_required()
def reminder_get_all_contacts():
# Get the user id
user_id = get_jwt_identity()

# Get all user contacts
contacts = Contact.query.filter_by(user_id=user_id)

# Serialize the data
return jsonify(contacts_schema.dump(contacts)), 200


@reminder.get("/birthday/upcoming")
@jwt_required()
def reminder_get_all_upcoming_birthdays():
# Get today's date
today = datetime.date.today()

# Find all users who birthdays are after today for the rest of the year
upcoming = (
db.session.query(Contact)
.filter(
extract("day", Contact.date_of_birth) >= today.day,
extract("month", Contact.date_of_birth) >= today.month,
user_id=get_jwt_identity(),
)
.order_by(
extract("day", Contact.date_of_birth),
extract("month", Contact.date_of_birth),
extract("year", Contact.date_of_birth),
)
.all()
)

return jsonify(contacts_schema.dump(upcoming)), 200


@reminder.get("/birthday/current")
@jwt_required()
def reminder_get_all_birthdays_current_year():
# Get today's date
today = datetime.date.today()

# Find all contacts
upcoming = (
db.session.query(Contact)
.filter(user_id=get_jwt_identity())
.order_by(
extract("day", Contact.date_of_birth),
extract("month", Contact.date_of_birth),
extract("year", Contact.date_of_birth),
)
.all()
)

return jsonify(contacts_schema.dump(upcoming)), 200
22 changes: 20 additions & 2 deletions backend/api/reminder/models.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from api import db
from sqlalchemy import Enum
from sqlalchemy import Enum, extract
import enum
from marshmallow import Schema, fields, post_load


class ContactRelation(enum.Enum):
father = 1
Expand All @@ -9,10 +11,26 @@ class ContactRelation(enum.Enum):
sister = 4
friend = 5


class Contact(db.Model):
__tablename__ = "contact"

id = db.Column(db.Integer, primary_key=True, autoincrement=True)
user_id = db.Column(
db.Integer, db.ForeignKey("custom_user.id", ondelete="cascade"), nullable=False
)
name = db.Column(db.String(100), nullable=False)
date_of_birth = db.Column(db.Date(), nullable=False)
relation = db.Column(Enum(ContactRelation))
relation = db.Column(Enum(ContactRelation))


class ContactSchema(Schema):
id = fields.Int(required=True, dump_only=True)
user_id = fields.Int(required=True, dump_only=True)
name = fields.Str(required=True)
date_of_birth = fields.Date(required=True)
relation = fields.Str(required=True)

@post_load
def make_user(self, data, **kwargs):
return Contact(**data)
3 changes: 2 additions & 1 deletion backend/api/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ def app():
flask_app.app_context().push()
yield flask_app


@pytest.fixture
def client(app):
yield app.test_client()
yield app.test_client()
21 changes: 18 additions & 3 deletions backend/api/tests/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,34 @@
"name": "Super User",
"email": "superu@email.com",
"type": "super",
"password": "testing1234"
"password": "testing1234",
}

test_user_1 = {
"name": "John Doe",
"email": "johndoe@email.com",
"type": "normal",
"password": "testing1234"
"password": "testing1234",
}

test_user_2 = {
"name": "Jane Doe",
"email": "janedoe@email.com",
"type": "normal",
"password": "testing1234"
"password": "testing1234",
}

# Contacts
valid_contacts = [
{"name": "Isabel Vasilevich", "date_of_birth": "2001-07-09", "relation": "sister"},
{"name": "Marshall Yeatman", "date_of_birth": "2001-10-30", "relation": "father"},
{"name": "Rogers McNirlin", "date_of_birth": "2001-02-13", "relation": "brother"},
{"name": "Bobinette Tollady", "date_of_birth": "2001-01-13", "relation": "friend"},
{"name": "Myca Berling", "date_of_birth": "2021-12-30", "relation": "friend"},
{"name": "Andrej Rudall", "date_of_birth": "2021-12-10", "relation": "friend"},
{"name": "Dalia Shannahan", "date_of_birth": "2021-12-16", "relation": "friend"},
{"name": "Amil Garlett", "date_of_birth": "2021-12-22", "relation": "friend"},
{"name": "Guy Haig", "date_of_birth": "2021-12-28", "relation": "friend"},
]

invalid_contact = [{"name": "Roselia Golda", "date_of_birth": "2001-10-01"}]

0 comments on commit cfcdd91

Please sign in to comment.