From ace1b1ed852f2035c8356e0f471f6941bd787583 Mon Sep 17 00:00:00 2001 From: Michael Weimann Date: Sat, 26 Jun 2021 10:51:39 +0200 Subject: [PATCH 1/3] seed entire profile --- README.md | 2 +- ki/actions/__init__.py | 1 + ki/actions/seed.py | 83 ++++++++++++++++++++++++++++++++ ki/commands.py | 41 +++------------- ki/test/test_login_endpoint.py | 10 ++-- ki/test/test_profile_endpoint.py | 29 +++-------- ki/test/test_skills_endpoint.py | 10 ++-- 7 files changed, 112 insertions(+), 64 deletions(-) create mode 100644 ki/actions/__init__.py create mode 100644 ki/actions/seed.py diff --git a/README.md b/README.md index 3e66ca0..4410caa 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ cp env.dev .env pipenv install --dev pipenv shell flask db upgrade -flask seed +flask seed --dev flask run ``` diff --git a/ki/actions/__init__.py b/ki/actions/__init__.py new file mode 100644 index 0000000..fb33903 --- /dev/null +++ b/ki/actions/__init__.py @@ -0,0 +1 @@ +from ki.actions.seed import seed # noqa diff --git a/ki/actions/seed.py b/ki/actions/seed.py new file mode 100644 index 0000000..8be1889 --- /dev/null +++ b/ki/actions/seed.py @@ -0,0 +1,83 @@ +import csv +import logging + +from app import app, db +from ki.models import Address, Contact, ContactType, Language, Skill, Profile, ProfileLanguage, ProfileSkill, User + + +def seed(dev: bool): + skill_seed_file_path = app.config["KI_DATA_DIR"] + "/seed_data/skills.csv" + + logging.info("importing skills") + + with open(skill_seed_file_path) as skills_file: + skills_csv_reader = csv.DictReader(skills_file) + + for skill in skills_csv_reader: + id = int(skill["id"]) + db_skill = Skill.query.get(id) + + if db_skill is None: + db.session.add(Skill(id=int(skill["id"]), name=skill["name"])) + + logging.info("importing languages") + + iso_seed_file_path = app.config["KI_DATA_DIR"] + "/seed_data/iso_639_1.csv" + + with open(iso_seed_file_path) as iso_file: + iso_csv_reader = csv.DictReader(iso_file) + + for iso in iso_csv_reader: + id = iso["639-1"] + db_language = Language.query.get(id) + + if db_language is None: + db.session.add(Language(id=iso["639-1"], name=iso["Sprache"])) + + if dev: + logging.info("seeding peter :)") + + peter = User(auth_id="peter") + db.session.add(peter) + + peters_profile = Profile(nickname="peternichtlustig", + pronouns="Herr Dr. Dr.", + volunteerwork="Gartenverein", + freetext="Ich mag Kaffee", + user=peter) + db.session.add(peters_profile) + + matrix_type = ContactType(name="Matrix") + db.session.add(matrix_type) + + matrix_contact = Contact(profile=peters_profile, + contacttype=matrix_type, + content="@peter:wtf-eg.de") + db.session.add(matrix_contact) + + peters_address = Address(name="Peter Nichtlustig", + street="Waldweg", + house_number="23i", + additional="Hinterhaus", + postcode="13337", + city="Bielefeld", + country="Deutschland", + profile=peters_profile) + db.session.add(peters_address) + + peters_python_skill = ProfileSkill(profile=peters_profile, + skill_id=3, + level=5) + db.session.add(peters_python_skill) + + peter_de = ProfileLanguage(profile=peters_profile, + language_id="de", + level=5) + db.session.add(peter_de) + + peter_fr = ProfileLanguage(profile=peters_profile, + language_id="fr", + level=3) + db.session.add(peter_fr) + + db.session.commit() diff --git a/ki/commands.py b/ki/commands.py index 3382708..c20c71e 100644 --- a/ki/commands.py +++ b/ki/commands.py @@ -1,39 +1,10 @@ -import csv +import click -from ki.models import Language, Skill -from app import app, db - - -def seed(): - skill_seed_file_path = app.config["KI_DATA_DIR"] + "/seed_data/skills.csv" - - print("importing skills") - - with open(skill_seed_file_path) as skills_file: - skills_csv_reader = csv.DictReader(skills_file) - - for skill in skills_csv_reader: - id = int(skill["id"]) - db_skill = Skill.query.get(id) - - if db_skill is None: - db.session.add(Skill(id=int(skill["id"]), name=skill["name"])) - - iso_seed_file_path = app.config["KI_DATA_DIR"] + "/seed_data/iso_639_1.csv" - - with open(iso_seed_file_path) as iso_file: - iso_csv_reader = csv.DictReader(iso_file) - - for iso in iso_csv_reader: - id = iso["639-1"] - db_language = Language.query.get(id) - - if db_language is None: - db.session.add(Language(id=iso["639-1"], name=iso["Sprache"])) - - db.session.commit() +from app import app +from ki.actions import seed @app.cli.command("seed") -def seed_command(): - seed() +@click.option("--dev", is_flag=True) +def seed_command(dev): + seed(dev) diff --git a/ki/test/test_login_endpoint.py b/ki/test/test_login_endpoint.py index 86c48c2..314de11 100644 --- a/ki/test/test_login_endpoint.py +++ b/ki/test/test_login_endpoint.py @@ -2,8 +2,8 @@ from alembic import command import json import unittest -from app import app, migrate -from ki.commands import seed +from app import app, db, migrate +from ki.actions import seed class TestLoginEndpoint(unittest.TestCase): @@ -16,7 +16,11 @@ class TestLoginEndpoint(unittest.TestCase): config = migrate.get_config() command.upgrade(config, "head") - seed() + seed(True) + + def tearDown(self): + db.drop_all() + db.engine.dispose() def test_login(self): response1_data = self.login() diff --git a/ki/test/test_profile_endpoint.py b/ki/test/test_profile_endpoint.py index 44ea8ed..2295116 100644 --- a/ki/test/test_profile_endpoint.py +++ b/ki/test/test_profile_endpoint.py @@ -3,8 +3,8 @@ import unittest import json from app import app, db, migrate -from ki.commands import seed -from ki.models import Profile, User +from ki.actions import seed +from ki.models import User class TestProfileEndpoint(unittest.TestCase): @@ -15,22 +15,16 @@ class TestProfileEndpoint(unittest.TestCase): self.client = app.test_client() with app.app_context(): - db.drop_all() - db.engine.dispose() config = migrate.get_config() command.upgrade(config, "head") - seed() + seed(True) def tearDown(self): db.drop_all() db.engine.dispose() def test_create_profile(self): - user = User(auth_id="peter") - db.session.add(user) - db.session.commit() - login_data = {"username": "peter", "password": "geheim"} login_response = self.client.post("/users/login", data=json.dumps(login_data), @@ -62,15 +56,6 @@ class TestProfileEndpoint(unittest.TestCase): self.assertEqual("Hallo", profile.freetext) 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), @@ -89,10 +74,10 @@ class TestProfileEndpoint(unittest.TestCase): self.assertEqual( response.json, { "profile": { - "freetext": "", - "nickname": "Popeter", - "pronouns": "", - "volunteerwork": "" + "freetext": "Ich mag Kaffee", + "nickname": "peternichtlustig", + "pronouns": "Herr Dr. Dr.", + "volunteerwork": "Gartenverein" } }) diff --git a/ki/test/test_skills_endpoint.py b/ki/test/test_skills_endpoint.py index 9287c65..57c9cb5 100644 --- a/ki/test/test_skills_endpoint.py +++ b/ki/test/test_skills_endpoint.py @@ -1,8 +1,8 @@ from alembic import command import unittest -from app import app, migrate -from ki.commands import seed +from app import app, db, migrate +from ki.actions import seed class TestSkillsEndpoint(unittest.TestCase): @@ -15,7 +15,11 @@ class TestSkillsEndpoint(unittest.TestCase): config = migrate.get_config() command.upgrade(config, "head") - seed() + seed(True) + + def tearDown(self): + db.drop_all() + db.engine.dispose() def test_skills_options(self): response = self.client.options("/skills") From 3bd9b0300218a2c0d21913f099a37251c3ab4eee Mon Sep 17 00:00:00 2001 From: Michael Weimann Date: Sat, 26 Jun 2021 11:40:29 +0200 Subject: [PATCH 2/3] add yapf config file --- .style.yapf | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .style.yapf diff --git a/.style.yapf b/.style.yapf new file mode 100644 index 0000000..c1b9715 --- /dev/null +++ b/.style.yapf @@ -0,0 +1,3 @@ +[style] +based_on_style = pep8 +allow_split_before_dict_value = 0 From fc01bec163b3b798309ae6100f5ef54dbd922e82 Mon Sep 17 00:00:00 2001 From: Michael Weimann Date: Sat, 26 Jun 2021 12:16:14 +0200 Subject: [PATCH 3/3] return full profile response --- ki/models.py | 62 +++++++++++++++++++++++++++-- ki/routes.py | 4 +- ki/test/test_profile_endpoint.py | 68 +++++++++++++++++++++++++++----- ki/test/test_skills_endpoint.py | 6 ++- 4 files changed, 124 insertions(+), 16 deletions(-) diff --git a/ki/models.py b/ki/models.py index 77014f6..423133b 100644 --- a/ki/models.py +++ b/ki/models.py @@ -42,10 +42,17 @@ class Profile(db.Model): def to_dict(self): return { + "user_id": self.user.id, "nickname": self.nickname, "pronouns": self.pronouns, "volunteerwork": self.volunteerwork, - "freetext": self.freetext + "freetext": self.freetext, + "address": self.address.to_dict(), + "contacts": list( + map(lambda contact: contact.to_dict(), self.contacts)), + "skills": list(map(lambda skill: skill.to_dict(), self.skills)), + "languages": list( + map(lambda language: language.to_dict(), self.languages)) } @@ -58,6 +65,9 @@ class Token(db.Model): user = relationship("User", back_populates="tokens") + def to_dict(self): + return {"user_id": self.user_id, "token": self.token} + class Contact(db.Model): __tablename__ = "contact" @@ -71,6 +81,14 @@ class Contact(db.Model): contacttype = relationship("ContactType") content = Column(String(200), nullable=False) + def to_dict(self): + return { + "id": self.id, + "profile_id": self.profile_id, + "contacttype": self.contacttype.to_dict(), + "content": self.content + } + class ContactType(db.Model): __tablename__ = "contacttype" @@ -78,6 +96,9 @@ class ContactType(db.Model): id = Column(Integer, primary_key=True) name = Column(String(25), nullable=False) + def to_dict(self): + return {"id": self.id, "name": self.name} + class Address(db.Model): __tablename__ = "address" @@ -94,6 +115,19 @@ class Address(db.Model): profile_id = Column(Integer, ForeignKey("profile.id"), nullable=False) profile = relationship("Profile", back_populates="address") + def to_dict(self): + return { + "id": self.id, + "name": self.name, + "street": self.street, + "house_number": self.house_number, + "additional": self.additional, + "postcode": self.postcode, + "city": self.city, + "country": self.country, + "profile_id": self.profile_id + } + class Skill(db.Model): __tablename__ = "skill" @@ -104,7 +138,11 @@ class Skill(db.Model): profiles = relationship("ProfileSkill", back_populates="skill") def to_dict(self): - return {"id": self.id, "name": self.name} + return { + "id": self.id, + "name": self.name, + "icon_url": "/skills/{}/icon".format(self.id) + } class ProfileSkill(db.Model): @@ -117,6 +155,13 @@ class ProfileSkill(db.Model): profile = relationship("Profile", back_populates="skills") skill = relationship("Skill", back_populates="profiles") + def to_dict(self): + return { + "profile_id": self.profile_id, + "skill": self.skill.to_dict(), + "level": self.level + } + class Language(db.Model): __tablename__ = "language" @@ -127,7 +172,11 @@ class Language(db.Model): profiles = relationship("ProfileLanguage", back_populates="language") def to_dict(self): - return {"id": self.id, "name": self.name} + return { + "id": self.id, + "name": self.name, + "icon_url": "/languages/{}/icon".format(self.id) + } class ProfileLanguage(db.Model): @@ -139,3 +188,10 @@ class ProfileLanguage(db.Model): profile = relationship("Profile", back_populates="languages") language = relationship("Language", back_populates="profiles") + + def to_dict(self): + return { + "profile_id": self.profile_id, + "language": self.language.to_dict(), + "level": self.level + } diff --git a/ki/routes.py b/ki/routes.py index b07c2d1..1dea412 100644 --- a/ki/routes.py +++ b/ki/routes.py @@ -115,7 +115,9 @@ def get_user_profile(user_id): if profile is None: return make_response({}, 404) - return make_response({"profile": profile.to_dict()}) + return make_response({ + "profile": profile.to_dict(), + }) @app.route("/users//profile", methods=["POST"]) diff --git a/ki/test/test_profile_endpoint.py b/ki/test/test_profile_endpoint.py index 2295116..9591795 100644 --- a/ki/test/test_profile_endpoint.py +++ b/ki/test/test_profile_endpoint.py @@ -8,6 +8,8 @@ from ki.models import User class TestProfileEndpoint(unittest.TestCase): + maxDiff = None + def setUp(self): app.debug = True app.config["TESTING"] = True @@ -24,7 +26,7 @@ class TestProfileEndpoint(unittest.TestCase): db.drop_all() db.engine.dispose() - def test_create_profile(self): + def test_update_profile(self): login_data = {"username": "peter", "password": "geheim"} login_response = self.client.post("/users/login", data=json.dumps(login_data), @@ -34,7 +36,7 @@ class TestProfileEndpoint(unittest.TestCase): self.assertIn("token", login_response.json) data = { - "pronouns": "Herr Dr. Dr.", + "pronouns": "Monsieur", "volunteerwork": "ja", "freetext": "Hallo", } @@ -42,8 +44,7 @@ class TestProfileEndpoint(unittest.TestCase): data=json.dumps(data), content_type="application/json", headers={ - "Authorization": - "Bearer " + + "Authorization": "Bearer " + login_response.json["token"] }) @@ -51,7 +52,7 @@ class TestProfileEndpoint(unittest.TestCase): with app.app_context(): user = User.query.filter(User.id == 1).first() profile = user.profile - self.assertEqual("Herr Dr. Dr.", profile.pronouns) + self.assertEqual("Monsieur", profile.pronouns) self.assertEqual("ja", profile.volunteerwork) self.assertEqual("Hallo", profile.freetext) @@ -66,18 +67,65 @@ class TestProfileEndpoint(unittest.TestCase): response = self.client.get("/users/1/profile", headers={ - "Authorization": - "Bearer " + login_response.json["token"] + "Authorization": "Bearer " + + login_response.json["token"] }) self.assertEqual(response.status_code, 200) - self.assertEqual( + self.assertDictEqual( response.json, { "profile": { - "freetext": "Ich mag Kaffee", + "user_id": 1, "nickname": "peternichtlustig", "pronouns": "Herr Dr. Dr.", - "volunteerwork": "Gartenverein" + "freetext": "Ich mag Kaffee", + "volunteerwork": "Gartenverein", + "address": { + "additional": "Hinterhaus", + "city": "Bielefeld", + "country": "Deutschland", + "house_number": "23i", + "id": 1, + "name": "Peter Nichtlustig", + "postcode": "13337", + "profile_id": 1, + "street": "Waldweg" + }, + "contacts": [{ + "id": 1, + "profile_id": 1, + "contacttype": { + "id": 1, + "name": "Matrix" + }, + "content": "@peter:wtf-eg.de" + }], + "skills": [{ + "profile_id": 1, + "skill": { + "id": 3, + "name": "Python", + "icon_url": "/skills/3/icon" + }, + "level": 5 + }], + "languages": [{ + "profile_id": 1, + "language": { + "id": "de", + "name": "Deutsch", + "icon_url": "/languages/de/icon" + }, + "level": 5 + }, { + "profile_id": 1, + "language": { + "id": "fr", + "name": "Französisch", + "icon_url": "/languages/fr/icon" + }, + "level": 3 + }] } }) diff --git a/ki/test/test_skills_endpoint.py b/ki/test/test_skills_endpoint.py index 57c9cb5..76fb283 100644 --- a/ki/test/test_skills_endpoint.py +++ b/ki/test/test_skills_endpoint.py @@ -34,10 +34,12 @@ class TestSkillsEndpoint(unittest.TestCase): { "skills": [{ "id": 1, - "name": "PHP" + "name": "PHP", + "icon_url": "/skills/1/icon" }, { "id": 3, - "name": "Python" + "name": "Python", + "icon_url": "/skills/3/icon" }] }, response.json) self.assertIn("Access-Control-Allow-Origin", response.headers)