implement generic search
All checks were successful
continuous-integration/drone/push Build is passing

closes #47
This commit is contained in:
weeman 2021-08-16 22:41:03 +02:00
parent ec855a542d
commit b8c2644086
Signed by: weeman
GPG Key ID: 34F0524D4DA694A1
4 changed files with 107 additions and 19 deletions

View File

@ -26,6 +26,31 @@ def seed_contacttypes():
db.session.add(ContactType(id=int(contacttype["id"]), name=contacttype["name"])) db.session.add(ContactType(id=int(contacttype["id"]), name=contacttype["name"]))
def seed_user(nickname, visible=False, skills=[], languages=[], volunteerwork="", availability="", freetext=""):
app.logger.info(f"seeding {nickname} \\o/")
user = User(auth_id=nickname)
db.session.add(user)
profile = Profile(nickname=nickname,
pronouns="",
volunteerwork=volunteerwork,
availability=availability,
freetext=freetext,
visible=visible,
user=user)
for skill_data in skills:
skill = ProfileSkill(profile=profile, skill_id=skill_data[0], level=skill_data[1])
db.session.add(skill)
for language_data in languages:
language = ProfileLanguage(profile=profile, language_id=language_data[0], level=language_data[1])
db.session.add(language)
db.session.add(profile)
def seed(dev: bool): def seed(dev: bool):
seed_contacttypes() seed_contacttypes()
@ -105,23 +130,21 @@ def seed(dev: bool):
peter_fr = ProfileLanguage(profile=peters_profile, language_id="fr", level=3) peter_fr = ProfileLanguage(profile=peters_profile, language_id="fr", level=3)
db.session.add(peter_fr) db.session.add(peter_fr)
app.logger.info("seeding klaus :D") seed_user("klaus")
klaus = User(auth_id="klaus") seed_user("dirtydieter",
db.session.add(klaus) visible=True,
app.logger.info("seeding dieter \\o/")
dieter = User(auth_id="dieter")
db.session.add(dieter)
dieters_profile = Profile(nickname="dirtydieter",
pronouns="",
volunteerwork="Müll sammeln", volunteerwork="Müll sammeln",
availability="Nur nachts", availability="Nur nachts",
freetext="1001010010111!!!", freetext="1001010010111!!!",
skills=[(Skill.skill_id_php, 5)])
seed_user("jutta",
visible=True, visible=True,
user=dieter) languages=[("fr", 5)],
db.session.add(dieters_profile) skills=[(Skill.skill_id_php, 3), (Skill.skill_id_mysql, 4)])
seed_user("giesela", visible=True, skills=[(Skill.skill_id_mysql, 3), (Skill.skill_id_postgresql, 5)])
seed_user("bertha", visible=False, skills=[(Skill.skill_id_sqlite, 3), (Skill.skill_id_postgresql, 5)])
seed_user("monique", visible=True, languages=[("fr", 4)])
db.session.commit() db.session.commit()

View File

@ -4,7 +4,7 @@
from flask import make_response, request from flask import make_response, request
from ki.models import Profile from ki.models import Profile, ProfileSkill, Skill, ProfileLanguage, Language
def find_profiles(): def find_profiles():
@ -18,13 +18,21 @@ def find_profiles():
if page_size > 100: if page_size > 100:
return make_response({"messages": {"page_size": "Die maximale Anzahl Einträge pro Seite beträgt 100"}}, 400) return make_response({"messages": {"page_size": "Die maximale Anzahl Einträge pro Seite beträgt 100"}}, 400)
query = Profile.query.filter(Profile.visible.is_(True)) query = Profile.query.filter(Profile.visible.is_(True)) \
.join(Profile.skills, isouter=True).join(ProfileSkill.skill, isouter=True) \
.join(Profile.languages, isouter=True).join(ProfileLanguage.language, isouter=True)
if "search" in request.args:
terms = request.args["search"].split(" ")
for term in terms:
query = query.filter(
Profile.nickname.like(f"%{term}%") | Skill.name.like(f"%{term}%") | Language.name.like(f"%{term}%"))
if "nickname" in request.args: if "nickname" in request.args:
nickname = request.args.get("nickname") nickname = request.args.get("nickname")
query = query.filter(Profile.nickname.like(f"%{nickname}%")) query = query.filter(Profile.nickname.like(f"%{nickname}%"))
count = query.count() count = query.distinct(Profile.id).count()
offset = (page - 1) * page_size offset = (page - 1) * page_size
db_profiles = query.limit(page_size).offset(offset).all() db_profiles = query.limit(page_size).offset(offset).all()

View File

@ -133,6 +133,13 @@ class Address(db.Model):
class Skill(db.Model): class Skill(db.Model):
skill_id_php = 1
skill_id_python = 3
skill_id_sqlalchemy = 7
skill_id_mysql = 9
skill_id_postgresql = 10
skill_id_sqlite = 11
__tablename__ = "skill" __tablename__ = "skill"
id = Column(Integer, primary_key=True) id = Column(Integer, primary_key=True)

View File

@ -34,9 +34,59 @@ class TestFindProfilesEndpoint(ApiTest):
response = self.client.get("/users/profiles", headers={"Authorization": "Bearer " + token}) response = self.client.get("/users/profiles", headers={"Authorization": "Bearer " + token})
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
self.assertDictContainsSubset({"total": 4}, response.json)
self.assertDictContainsSubset({"nickname": "dirtydieter"}, response.json["profiles"][0])
def test_find_dieter(self):
token = self.login("peter", "geheim")["token"]
response = self.client.get("/users/profiles?search=dieter%20php", headers={"Authorization": "Bearer " + token})
self.assertEqual(response.status_code, 200)
self.assertDictContainsSubset({"total": 1}, response.json) self.assertDictContainsSubset({"total": 1}, response.json)
self.assertDictContainsSubset({"nickname": "dirtydieter"}, response.json["profiles"][0]) self.assertDictContainsSubset({"nickname": "dirtydieter"}, response.json["profiles"][0])
def test_not_find_dieter(self):
token = self.login("peter", "geheim")["token"]
response = self.client.get("/users/profiles?search=dieter%20sqlite",
headers={"Authorization": "Bearer " + token})
self.assertEqual(response.status_code, 200)
self.assertDictContainsSubset({"total": 0}, response.json)
def test_find_sql(self):
token = self.login("peter", "geheim")["token"]
response = self.client.get("/users/profiles?search=sql", headers={"Authorization": "Bearer " + token})
self.assertEqual(response.status_code, 200)
self.assertDictContainsSubset({"total": 2}, response.json)
self.assertDictContainsSubset({"nickname": "jutta"}, response.json["profiles"][0])
self.assertDictContainsSubset({"nickname": "giesela"}, response.json["profiles"][1])
def test_find_postgres(self):
token = self.login("peter", "geheim")["token"]
response = self.client.get("/users/profiles?search=post", headers={"Authorization": "Bearer " + token})
self.assertEqual(response.status_code, 200)
self.assertDictContainsSubset({"total": 1}, response.json)
self.assertDictContainsSubset({"nickname": "giesela"}, response.json["profiles"][0])
def test_find_php_franzosen(self):
token = self.login("peter", "geheim")["token"]
response = self.client.get("/users/profiles?search=php%20franz", headers={"Authorization": "Bearer " + token})
self.assertEqual(response.status_code, 200)
self.assertDictContainsSubset({"total": 1}, response.json)
self.assertDictContainsSubset({"nickname": "jutta"}, response.json["profiles"][0])
def test_find_franzosen(self):
token = self.login("peter", "geheim")["token"]
response = self.client.get("/users/profiles?search=französisch", headers={"Authorization": "Bearer " + token})
self.assertEqual(response.status_code, 200)
self.assertDictContainsSubset({"total": 2}, response.json)
self.assertDictContainsSubset({"nickname": "jutta"}, response.json["profiles"][0])
self.assertDictContainsSubset({"nickname": "monique"}, response.json["profiles"][1])
if __name__ == "main": if __name__ == "main":
unittest.main() unittest.main()