Skip to content

Commit

Permalink
Merge pull request #17 from Maxcutex/PA-16-create-skill-crud-api-and-…
Browse files Browse the repository at this point in the history
…corresponding-tests

[WIP] - Pa 16 create skill crud api and corresponding tests
  • Loading branch information
Maxcutex committed Jan 25, 2021
2 parents 3060f3c + 411e0ba commit 685ce33
Show file tree
Hide file tree
Showing 12 changed files with 647 additions and 135 deletions.
1 change: 1 addition & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
exclude: '^vessel.py'
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v2.4.0
Expand Down
4 changes: 4 additions & 0 deletions app/blueprints/base_blueprint.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,19 @@ def register(self):
from app.blueprints.skills_category_blueprint import skills_category_blueprint
from app.blueprints.user_employment_blueprint import user_employment_blueprint
from app.blueprints.user_project_blueprint import user_project_blueprint
from app.blueprints.skill_blueprint import skill_blueprint

from app.blueprints.user_skill_blueprint import user_skill_blueprint
from app.blueprints.user_education_blueprint import user_education_blueprint


self.app.register_blueprint(home_blueprint)
self.app.register_blueprint(activity_blueprint)
self.app.register_blueprint(role_blueprint)
self.app.register_blueprint(user_blueprint)
self.app.register_blueprint(skills_category_blueprint)
self.app.register_blueprint(user_employment_blueprint)
self.app.register_blueprint(user_project_blueprint)
self.app.register_blueprint(skill_blueprint)
self.app.register_blueprint(user_skill_blueprint)
self.app.register_blueprint(user_education_blueprint)
55 changes: 55 additions & 0 deletions app/blueprints/skill_blueprint.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
from app.blueprints.base_blueprint import (
Blueprint,
BaseBlueprint,
request,
Security,
Auth,
)
from app.controllers.skill_controller import SkillController

url_prefix = "{}/skills".format(BaseBlueprint.base_url_prefix)
skill_blueprint = Blueprint("skill", __name__, url_prefix=url_prefix)
skill_controller = SkillController(request)


@skill_blueprint.route("/", methods=["GET"])
@Auth.has_permission(["view_skill"])
def list_skills():
return skill_controller.list_skills()


@skill_blueprint.route("/<int:id>/", methods=["GET"])
@Auth.has_permission(["view_skill"])
def get_skill(skill_id):
return skill_controller.get_skill(skill_id)


@skill_blueprint.route("/", methods=["POST"])
@Security.validator(
[
"name|required:string",
"skill_category_id|required:int",
]
)
@Auth.has_permission(["create_skill"])
def create_skill():
return skill_controller.create_skill()


@skill_blueprint.route("/<int:skill_id>", methods=["PUT", "PATCH"])
@Security.validator(
[
"skill_id|required:int",
"name|required:string",
"skill_category_id|required:int",
]
)
@Auth.has_permission(["update_skill"])
def update_skill(skill_id):
return skill_controller.update_skill(skill_id)


@skill_blueprint.route("/<int:skill_id>", methods=["DELETE"])
@Auth.has_permission(["delete_skill"])
def delete_skill(skill_id):
return skill_controller.delete_skill(skill_id)
84 changes: 84 additions & 0 deletions app/controllers/skill_controller.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
from app.controllers.base_controller import BaseController
from app.repositories.skill_repo import SkillRepo


class SkillController(BaseController):
def __init__(self, request):
BaseController.__init__(self, request)
self.skill_repo = SkillRepo()

def list_skills(self):
skills = self.skill_repo.get_unpaginated()
skill_list = [skill.serialize() for skill in skills.items]
return self.handle_response(
"OK",
payload={
"skills": skill_list,
},
)

def get_skill(self, skill_id):
skill = self.skill_repo.find_first(id=skill_id)
if skill:
return self.handle_response("OK", payload={"skill": skill.serialize()})
return self.handle_response("Invalid or Missing skill_id", status_code=400)

def create_skill(self):
name, skill_category_id = self.request_params("name", "skill_category_id")
skill = self.skill_repo.find_first(
name=name, skill_category_id=skill_category_id
)

if skill:
print("testing ....")
return self.handle_response(
f"Skill name {skill.name} with category name {skill.skill_category.name} already exists",
status_code=400,
)
skill = self.skill_repo.new_skill(
name=name, skill_category_id=skill_category_id
)

return self.handle_response(
"OK", payload={"skill": skill.serialize()}, status_code=201
)

def update_skill(self, update_id):
skill_id, name, skill_category_id = self.request_params(
"skill_id", "name", "skill_category_id"
)
skill = self.skill_repo.find_first(
name=name, skill_category_id=skill_category_id
)

skill_other = self.skill_repo.get(name=name)

if skill_id != update_id:
return self.handle_response(
"Invalid or incorrect skill_id provided", status_code=400
)

if skill:
if skill.id == skill_other.id:
skill = self.skill_repo.update(
skill, **dict(name=name, skill_category_id=skill_category_id)
)
return self.handle_response(
"OK", payload={"skill": skill.serialize()}, status_code=200
)
else:
return self.handle_response(
f"Skill name '{name}' with category name {skill_other.skill_category.name} already exists",
status_code=400,
)
return self.handle_response("Skill Not Found", status_code=404)

def delete_skill(self, skill_id):
skill = self.skill_repo.get(skill_id)
update_dict = {"is_deleted": True}
if skill:
self.skill_repo.update(**update_dict)
return self.handle_response("skill deleted", payload={"status": "success"})
return self.handle_response(
"Invalid or incorrect skill_id provided", status_code=404
)
13 changes: 4 additions & 9 deletions app/repositories/skill_repo.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,8 @@ class SkillRepo(BaseRepo):
def __init__(self):
BaseRepo.__init__(self, Skill)

def new_skill(self, name, skill_category_id, is_active=True, is_deleted=False):
new_skill = Skill(
name=name,
skill_category_id=skill_category_id,
is_active=is_active,
is_deleted=is_deleted,
)
def new_skill(self, name, skill_category_id):
skill = Skill(name=name, skill_category_id=skill_category_id)

new_skill.save()
return new_skill
skill.save()
return skill
2 changes: 0 additions & 2 deletions factories/skill_category_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ class Meta:
model = SkillCategory
sqlalchemy_session = db.session

id = factory.Sequence(lambda n: n)
name = factory.Faker("name")
help = factory.Faker("paragraph")
is_active = fake.boolean(chance_of_getting_true=75)
Expand Down Expand Up @@ -49,7 +48,6 @@ class SkillCategoryFactoryFake(factory.Factory):
class Meta:
model = SkillCategory

id = factory.Sequence(lambda n: n)
name = factory.Faker("name")
help = factory.Faker("paragraph")
is_active = fake.boolean(chance_of_getting_true=75)
Expand Down
16 changes: 16 additions & 0 deletions factories/skill_factory.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import factory
from app.utils import db
from app.models import Skill
from faker import Faker


class SkillFactory(factory.alchemy.SQLAlchemyModelFactory):

class Meta:
model = Skill
sqlalchemy_session = db.session

id = factory.Sequence(lambda n: n)
name = factory.Faker("city")
skill_category_id = factory.Sequence(lambda n: n)

11 changes: 11 additions & 0 deletions tests/integration/endpoints/test_skill_endpoints.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from tests.base_test_case import BaseTestCase

class TestSkillEndpoints(BaseTestCase):

def setUp(self):
self.BaseSetUp()


def tearDown(self):
self.BaseTearDown()

4 changes: 4 additions & 0 deletions tests/integration/endpoints/test_skills_category_endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,15 @@ def test_get_specific_skill_category_endpoint(self):
role = RoleFactory.create()
user_id = BaseTestCase.user_id()
skills_category = SkillCategoryFactory.create()
skills_category.save()
PermissionFactory.create(keyword="view_skills_categories", role=role)
UserRoleFactory.create(user_id=user_id, role=role)

response = self.client().get(
self.make_url("/skills_categories/{}".format(skills_category.id)),
headers=self.headers(),
)

response_json = self.decode_from_json_string(response.data.decode("utf-8"))
payload = response_json["payload"]

Expand Down Expand Up @@ -124,6 +126,7 @@ def test_invalid_update(self):
def test_delete_skill_category_endpoint_with_right_permission(self):
role = RoleFactory.create()
skills_category = SkillCategoryFactory.create()
skills_category.save()
user_id = BaseTestCase.user_id()

PermissionFactory.create(keyword="delete_skills_categories", role=role)
Expand All @@ -132,6 +135,7 @@ def test_delete_skill_category_endpoint_with_right_permission(self):
self.make_url(f"/skills_categories/{skills_category.id}"),
headers=self.headers(),
)

response_json = self.decode_from_json_string(response.data.decode("utf-8"))
payload = response_json["payload"]

Expand Down
Loading

0 comments on commit 685ce33

Please sign in to comment.