From 5c21e4c9b61d42c53605ee1b0949b120d9d3e1e5 Mon Sep 17 00:00:00 2001 From: Michael Weimann Date: Sun, 20 Jun 2021 19:25:27 +0200 Subject: [PATCH] extract profile --- ki/models.py | 70 +++++++++++------ ki/routes.py | 7 +- ki/test/test_profile_endpoint.py | 59 ++++++++++++++ ...n.py => f95308aceda1_initial_migration.py} | 77 ++++++++++--------- 4 files changed, 152 insertions(+), 61 deletions(-) create mode 100644 ki/test/test_profile_endpoint.py rename migrations/versions/{575a8924eb16_initial_migration.py => f95308aceda1_initial_migration.py} (72%) diff --git a/ki/models.py b/ki/models.py index 002f4bd..356aa79 100644 --- a/ki/models.py +++ b/ki/models.py @@ -9,25 +9,43 @@ from app import db class User(db.Model): __tablename__ = "user" + id = Column(Integer, primary_key=True) + auth_id = Column(String(50), nullable=False, unique=True) + profile_id = Column(Integer, ForeignKey("profile.id"), nullable=True) + + tokens = relationship("Token", uselist=False, back_populates="user") + profile = relationship("Profile", back_populates="user") + + def to_dict(self): + return {"id": self.id} + + +class Profile(db.Model): + __tablename__ = "profile" + id = Column(Integer, primary_key=True) nickname = Column(String(25), unique=True, nullable=False) pronouns = Column(String(25), default="") volunteerwork = Column(String(4000), default="") freetext = Column(String(4000), default="") created = Column(DateTime, nullable=False, default=datetime.now) - updated = Column(DateTime, onupdate=datetime.now, nullable=False, default=datetime.now) - auth_id = Column(String(50), nullable=False, unique=True) + updated = Column(DateTime, + onupdate=datetime.now, + nullable=False, + default=datetime.now) + user = relationship("User", back_populates="profile", uselist=False) contacts = relationship("Contact") - address = relationship("Address", uselist=False, back_populates="user") - tokens = relationship("Token", uselist=False, back_populates="user") - skills = relationship("UserSkill", back_populates="user") - languages = relationship("UserLanguage", back_populates="user") + address = relationship("Address", uselist=False, back_populates="profile") + skills = relationship("ProfileSkill", back_populates="profile") + languages = relationship("ProfileLanguage", back_populates="profile") def to_dict(self): return { - "id": self.id, - "nickname": self.nickname + "nickname": self.nickname, + "pronouns": self.pronouns, + "volunteerwork": self.volunteerwork, + "freetext": self.freetext } @@ -45,9 +63,11 @@ class Contact(db.Model): __tablename__ = "contact" id = Column(Integer, primary_key=True) - user_id = Column(Integer, ForeignKey("user.id"), nullable=False) - user = relationship("User", back_populates="contacts") - contacttype_id = Column(Integer, ForeignKey("contacttype.id"), nullable=False) + profile_id = Column(Integer, ForeignKey("profile.id"), nullable=False) + profile = relationship("Profile", back_populates="contacts") + contacttype_id = Column(Integer, + ForeignKey("contacttype.id"), + nullable=False) contacttype = relationship("ContactType") content = Column(String(200), nullable=False) @@ -71,8 +91,8 @@ class Address(db.Model): city = Column(String(25), default="") country = Column(String(25), default="") - user_id = Column(Integer, ForeignKey("user.id"), nullable=False) - user = relationship("User", back_populates="address") + profile_id = Column(Integer, ForeignKey("profile.id"), nullable=False) + profile = relationship("Profile", back_populates="address") class Skill(db.Model): @@ -81,21 +101,21 @@ class Skill(db.Model): id = Column(Integer, primary_key=True) name = Column(String(25), unique=True, nullable=False) - users = relationship("UserSkill", back_populates="skill") + profiles = relationship("ProfileSkill", back_populates="skill") def to_dict(self): return {"id": self.id, "name": self.name} -class UserSkill(db.Model): - __tablename__ = "user_skill" +class ProfileSkill(db.Model): + __tablename__ = "profile_skill" - user_id = Column(Integer, ForeignKey("user.id"), primary_key=True) + profile_id = Column(Integer, ForeignKey("profile.id"), primary_key=True) skill_id = Column(Integer, ForeignKey("skill.id"), primary_key=True) level = Column(SmallInteger, nullable=False) - user = relationship("User", back_populates="skills") - skill = relationship("Skill", back_populates="users") + profile = relationship("Profile", back_populates="skills") + skill = relationship("Skill", back_populates="profiles") class Language(db.Model): @@ -104,18 +124,18 @@ class Language(db.Model): id = Column(String(2), primary_key=True) name = Column(String(25), nullable=False) - users = relationship("UserLanguage", back_populates="language") + profiles = relationship("ProfileLanguage", back_populates="language") def to_dict(self): return {"id": self.id, "name": self.name} -class UserLanguage(db.Model): - __tablename__ = "user_language" +class ProfileLanguage(db.Model): + __tablename__ = "profile_language" - user_id = Column(Integer, ForeignKey("user.id"), primary_key=True) + profile_id = Column(Integer, ForeignKey("profile.id"), primary_key=True) language_id = Column(Integer, ForeignKey("language.id"), primary_key=True) level = Column(SmallInteger, nullable=False) - user = relationship("User", back_populates="languages") - language = relationship("Language", back_populates="users") + profile = relationship("Profile", back_populates="languages") + language = relationship("Language", back_populates="profiles") diff --git a/ki/routes.py b/ki/routes.py index 34247af..98dbc29 100644 --- a/ki/routes.py +++ b/ki/routes.py @@ -110,7 +110,12 @@ def get_user_profile(user_id): if user is None: return make_response({}, 404) - return make_response({"user": user.to_dict()}) + profile = user.profile + + if profile is None: + return make_response({}, 404) + + return make_response({"profile": profile.to_dict()}) @app.route("/skills") diff --git a/ki/test/test_profile_endpoint.py b/ki/test/test_profile_endpoint.py new file mode 100644 index 0000000..7dd1bec --- /dev/null +++ b/ki/test/test_profile_endpoint.py @@ -0,0 +1,59 @@ +from alembic import command +import unittest +import json + +from app import app, db, migrate +from ki.commands import seed +from ki.models import Profile, User + + +class TestProfileEndpoint(unittest.TestCase): + def setUp(self): + app.debug = True + app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///:memory:" + self.client = app.test_client() + + with app.app_context(): + config = migrate.get_config() + command.upgrade(config, "head") + + seed() + + def test_get_profile(self): + user = User(auth_id="peter") + db.session.add(user) + + profile = Profile(user=user) + profile.nickname = "Popeter" + db.session.add(profile) + + db.session.commit() + + login_data = {"username": "peter", "password": "geheim"} + login_response = self.client.post("/users/login", + data=json.dumps(login_data), + content_type="application/json") + + self.assertEqual(login_response.status_code, 200) + self.assertIn("token", login_response.json) + + response = self.client.get("/users/1/profile", + headers={ + "Authorization": + "Bearer " + login_response.json["token"] + }) + + self.assertEqual(response.status_code, 200) + self.assertEqual( + response.json, { + "profile": { + "freetext": "", + "nickname": "Popeter", + "pronouns": "", + "volunteerwork": "" + } + }) + + +if __name__ == "main": + unittest.main() diff --git a/migrations/versions/575a8924eb16_initial_migration.py b/migrations/versions/f95308aceda1_initial_migration.py similarity index 72% rename from migrations/versions/575a8924eb16_initial_migration.py rename to migrations/versions/f95308aceda1_initial_migration.py index 655f328..8aa7429 100644 --- a/migrations/versions/575a8924eb16_initial_migration.py +++ b/migrations/versions/f95308aceda1_initial_migration.py @@ -1,8 +1,8 @@ -"""Initial migration +"""Initial migration. -Revision ID: 575a8924eb16 +Revision ID: f95308aceda1 Revises: -Create Date: 2021-06-12 13:18:24.903142 +Create Date: 2021-06-20 19:11:47.086814 """ from alembic import op @@ -10,7 +10,7 @@ import sqlalchemy as sa # revision identifiers, used by Alembic. -revision = '575a8924eb16' +revision = 'f95308aceda1' down_revision = None branch_labels = None depends_on = None @@ -28,13 +28,7 @@ def upgrade(): sa.Column('name', sa.String(length=25), nullable=False), sa.PrimaryKeyConstraint('id') ) - op.create_table('skill', - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('name', sa.String(length=25), nullable=False), - sa.PrimaryKeyConstraint('id'), - sa.UniqueConstraint('name') - ) - op.create_table('user', + op.create_table('profile', sa.Column('id', sa.Integer(), nullable=False), sa.Column('nickname', sa.String(length=25), nullable=False), sa.Column('pronouns', sa.String(length=25), nullable=True), @@ -42,11 +36,15 @@ def upgrade(): sa.Column('freetext', sa.String(length=4000), nullable=True), sa.Column('created', sa.DateTime(), nullable=False), sa.Column('updated', sa.DateTime(), nullable=False), - sa.Column('auth_id', sa.String(length=50), nullable=False), sa.PrimaryKeyConstraint('id'), - sa.UniqueConstraint('auth_id'), sa.UniqueConstraint('nickname') ) + op.create_table('skill', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('name', sa.String(length=25), nullable=False), + sa.PrimaryKeyConstraint('id'), + sa.UniqueConstraint('name') + ) op.create_table('address', sa.Column('id', sa.Integer(), nullable=False), sa.Column('name', sa.String(length=25), nullable=True), @@ -56,54 +54,63 @@ def upgrade(): sa.Column('postcode', sa.String(length=10), nullable=True), sa.Column('city', sa.String(length=25), nullable=True), sa.Column('country', sa.String(length=25), nullable=True), - sa.Column('user_id', sa.Integer(), nullable=True), - sa.ForeignKeyConstraint(['user_id'], ['user.id'], ), + sa.Column('profile_id', sa.Integer(), nullable=False), + sa.ForeignKeyConstraint(['profile_id'], ['profile.id'], ), sa.PrimaryKeyConstraint('id') ) op.create_table('contact', sa.Column('id', sa.Integer(), nullable=False), - sa.Column('user_id', sa.Integer(), nullable=True), - sa.Column('contacttype_id', sa.Integer(), nullable=True), + sa.Column('profile_id', sa.Integer(), nullable=False), + sa.Column('contacttype_id', sa.Integer(), nullable=False), sa.Column('content', sa.String(length=200), nullable=False), sa.ForeignKeyConstraint(['contacttype_id'], ['contacttype.id'], ), - sa.ForeignKeyConstraint(['user_id'], ['user.id'], ), + sa.ForeignKeyConstraint(['profile_id'], ['profile.id'], ), sa.PrimaryKeyConstraint('id') ) - op.create_table('token', - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('user_id', sa.Integer(), nullable=True), - sa.Column('token', sa.String(length=36), nullable=False), - sa.ForeignKeyConstraint(['user_id'], ['user.id'], ), - sa.PrimaryKeyConstraint('id') - ) - op.create_table('user_language', - sa.Column('user_id', sa.Integer(), nullable=False), + op.create_table('profile_language', + sa.Column('profile_id', sa.Integer(), nullable=False), sa.Column('language_id', sa.Integer(), nullable=False), sa.Column('level', sa.SmallInteger(), nullable=False), sa.ForeignKeyConstraint(['language_id'], ['language.id'], ), - sa.ForeignKeyConstraint(['user_id'], ['user.id'], ), - sa.PrimaryKeyConstraint('user_id', 'language_id') + sa.ForeignKeyConstraint(['profile_id'], ['profile.id'], ), + sa.PrimaryKeyConstraint('profile_id', 'language_id') ) - op.create_table('user_skill', - sa.Column('user_id', sa.Integer(), nullable=False), + op.create_table('profile_skill', + sa.Column('profile_id', sa.Integer(), nullable=False), sa.Column('skill_id', sa.Integer(), nullable=False), sa.Column('level', sa.SmallInteger(), nullable=False), + sa.ForeignKeyConstraint(['profile_id'], ['profile.id'], ), sa.ForeignKeyConstraint(['skill_id'], ['skill.id'], ), + sa.PrimaryKeyConstraint('profile_id', 'skill_id') + ) + op.create_table('user', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('auth_id', sa.String(length=50), nullable=False), + sa.Column('profile_id', sa.Integer(), nullable=True), + sa.ForeignKeyConstraint(['profile_id'], ['profile.id'], ), + sa.PrimaryKeyConstraint('id'), + sa.UniqueConstraint('auth_id') + ) + op.create_table('token', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('user_id', sa.Integer(), nullable=False), + sa.Column('token', sa.String(length=36), nullable=False), sa.ForeignKeyConstraint(['user_id'], ['user.id'], ), - sa.PrimaryKeyConstraint('user_id', 'skill_id') + sa.PrimaryKeyConstraint('id') ) # ### end Alembic commands ### def downgrade(): # ### commands auto generated by Alembic - please adjust! ### - op.drop_table('user_skill') - op.drop_table('user_language') op.drop_table('token') + op.drop_table('user') + op.drop_table('profile_skill') + op.drop_table('profile_language') op.drop_table('contact') op.drop_table('address') - op.drop_table('user') op.drop_table('skill') + op.drop_table('profile') op.drop_table('language') op.drop_table('contacttype') # ### end Alembic commands ###