finish tag implementation into services and resources.

This commit is contained in:
blake hardee 2024-11-20 16:28:52 -05:00
parent e3dbe59fb9
commit d38978b0e2
15 changed files with 442 additions and 73 deletions

View File

@ -16,7 +16,7 @@ openapi_tags = {
# TODO: Enable authorization by passing user uuid to API # TODO: Enable authorization by passing user uuid to API
# TODO: Create custom exceptions # TODO: Create custom exceptions
@api.get("", response_model=List[Resource], tags=["Resource"]) @api.get("", response_model=List[Resource], tags=["Resource"])
def get_all( def get_all_resources(
user_id: str, user_id: str,
resource_svc: ResourceService = Depends(), resource_svc: ResourceService = Depends(),
user_svc: UserService = Depends(), user_svc: UserService = Depends(),
@ -27,7 +27,7 @@ def get_all(
@api.get("/{id}", response_model=Resource, tags=["Resource"]) @api.get("/{id}", response_model=Resource, tags=["Resource"])
def get_by_id( def get__resource_by_id(
user_id: str, user_id: str,
id: int, id: int,
resource_svc: ResourceService = Depends(), resource_svc: ResourceService = Depends(),
@ -38,8 +38,8 @@ def get_by_id(
return resource return resource
@api.post("/", response_model=Resource, tags=["Resource"]) @api.post("", response_model=Resource, tags=["Resource"])
def create_service( def create_resource(
user_id: str, user_id: str,
resource: Resource, resource: Resource,
resource_svc: ResourceService = Depends(), resource_svc: ResourceService = Depends(),
@ -50,8 +50,8 @@ def create_service(
return new_resource return new_resource
@api.put("/{resource_id}", response_model=Resource, tags=["Resource"]) @api.put("/{id}", response_model=Resource, tags=["Resource"])
def update_service( def update_resource(
resource_id: int, resource_id: int,
user_id: str, user_id: str,
resource: Resource, resource: Resource,
@ -65,8 +65,8 @@ def update_service(
return updated_resource return updated_resource
@api.delete("/{resource_id}", response_model=Resource, tags=["Resource"]) @api.delete("/{id}", response_model=Resource, tags=["Resource"])
def delete_service_tag_by_id( def delete_resource_tag_by_id(
resource_id: int, resource_id: int,
tag_id: int, tag_id: int,
user_id: str, user_id: str,
@ -79,3 +79,32 @@ def delete_service_tag_by_id(
resource_svc.remove_tag(subject, resource, tag) resource_svc.remove_tag(subject, resource, tag)
return resource_svc.get_resource_by_id(resource_id) return resource_svc.get_resource_by_id(resource_id)
@api.delete("/{resource_id}", tags=["Resource"])
def delete_resource_by_id(
resource_id: int,
user_id: str,
resource_svc: ResourceService = Depends(),
user_svc: UserService = Depends(),
):
subject = user_svc.get_user_by_uuid(user_id)
resource = resource_svc.get_by_id(resource_id)
resource_svc.delete(subject, resource)
return
@api.get("/search/", response_model=List[Resource], tags=["Resource"])
def get_service_by_slug(
slug: str,
user_id: str,
resource_svc: ResourceService = Depends(),
user_svc: UserService = Depends(),
):
subject = user_svc.get_user_by_uuid(user_id)
return resource_svc.get_by_slug(subject, slug)
@api.get("/tag/{tag_id}", response_model=List[Resource], tags=["Resource"])
def get_resources_by_tag(tag_id: int, resource_svc: ResourceService = Depends()):
return resource_svc.get_by_tag_id(tag_id)

View File

@ -1,4 +1,7 @@
from fastapi import APIRouter, Depends, HTTPException from fastapi import APIRouter, Depends, HTTPException
from pytest import Session
from backend.database import db_session
from ..services import ServiceService, UserService, TagService from ..services import ServiceService, UserService, TagService
from ..models import Service, Tag from ..models import Service, Tag
@ -16,18 +19,17 @@ openapi_tags = {
# TODO: Enable authorization by passing user uuid to API # TODO: Enable authorization by passing user uuid to API
# TODO: Create custom exceptions # TODO: Create custom exceptions
@api.get("", response_model=List[Service], tags=["Service"]) @api.get("", response_model=List[Service], tags=["Service"])
def get_all( def get_all_services(
user_id: str, user_id: str,
service_svc: ServiceService = Depends(), service_svc: ServiceService = Depends(),
user_svc: UserService = Depends(), user_svc: UserService = Depends(),
): ):
subject = user_svc.get_user_by_uuid(user_id) subject = user_svc.get_user_by_uuid(user_id)
return service_svc.get_service_by_user(subject) return service_svc.get_service_by_user(subject)
@api.get("/{id}", response_model=Service, tags=["Service"]) @api.get("/{id}", response_model=Service, tags=["Service"])
def get_by_id( def get_service_by_id(
user_id: str, user_id: str,
id: int, id: int,
service_svc: ServiceService = Depends(), service_svc: ServiceService = Depends(),
@ -38,7 +40,7 @@ def get_by_id(
return service return service
@api.post("/", response_model=Service, tags=["Service"]) @api.post("", response_model=Service, tags=["Service"])
def create_service( def create_service(
user_id: str, user_id: str,
service: Service, service: Service,
@ -65,7 +67,7 @@ def update_service(
return updated_service return updated_service
@api.delete("/{service_id}", response_model=Service, tags=["Service"]) @api.delete("/{service_id}/{tag_id}", response_model=Service, tags=["Service"])
def delete_service_tag_by_id( def delete_service_tag_by_id(
service_id: int, service_id: int,
tag_id: int, tag_id: int,
@ -79,3 +81,29 @@ def delete_service_tag_by_id(
service_svc.remove_tag(subject, service, tag) service_svc.remove_tag(subject, service, tag)
return service_svc.get_service_by_id(service_id) return service_svc.get_service_by_id(service_id)
@api.delete("/{service_id}", tags=["Service"])
def delete_service_by_id(
service_id: int,
user_id: str,
service_svc: ServiceService = Depends(),
user_svc: UserService = Depends(),
):
subject = user_svc.get_user_by_uuid(user_id)
service = service_svc.get_service_by_id(service_id)
service_svc.delete(subject, service)
return
@api.get("/search/", response_model=List[Service], tags=["Service"])
def get_service_by_slug(
slug: str,
service_svc: ServiceService = Depends(),
):
return service_svc.get_service_by_slug(slug)
@api.get("/tag/{tag_id}", response_model=List[Service], tags=["Service"])
def get_services_by_tag(tag_id: int, service_svc: ServiceService = Depends()):
return service_svc.get_service_by_tag_id(tag_id)

22
backend/api/tag.py Normal file
View File

@ -0,0 +1,22 @@
from typing import List
from fastapi import APIRouter, Depends
from backend.models.resource_model import Resource
from backend.models.service_model import Service
from backend.models.tag_model import Tag
from backend.services.resource import ResourceService
from backend.services.service import ServiceService
from backend.services.tag import TagService
api = APIRouter(prefix="/api/tag")
openapi_tags = {
"name": "Tag",
"description": "Tag getter and related operations.",
}
@api.get("", response_model=List[Tag], tags=["tags"])
def get_all_tags(tag_service: TagService = Depends()):
return tag_service.all()

View File

@ -49,7 +49,6 @@ class ResourceEntity(EntityBase):
return cls( return cls(
id=model.id, id=model.id,
created_at=model.created_at,
name=model.name, name=model.name,
summary=model.summary, summary=model.summary,
link=model.link, link=model.link,

View File

@ -50,6 +50,7 @@ class ServiceEntity(EntityBase):
summary=self.summary, summary=self.summary,
requirements=self.requirements, requirements=self.requirements,
program=self.program, program=self.program,
created_at=self.created_at,
tags=[tag.tag.to_model() for tag in self.service_tags], tags=[tag.tag.to_model() for tag in self.service_tags],
) )

View File

@ -13,5 +13,5 @@ class Resource(BaseModel):
summary: str = Field(..., max_length=300, description="The summary of the resource") summary: str = Field(..., max_length=300, description="The summary of the resource")
link: str = Field(..., max_length=150, description="link to the resource") link: str = Field(..., max_length=150, description="link to the resource")
program: ProgramTypeEnum program: ProgramTypeEnum
created_at: Optional[datetime] created_at: datetime | None = None
tags: List[Tag] = [] tags: List[Tag] = []

View File

@ -1,12 +1,13 @@
from typing import List
from fastapi import Depends from fastapi import Depends
from backend.services.tag import TagService from backend.services.tag import TagService
from ..database import db_session from ..database import db_session
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from sqlalchemy import select from sqlalchemy import and_, or_, select
from ..models.resource_model import Resource from ..models.resource_model import Resource
from ..entities.resource_entity import ResourceEntity from ..entities.resource_entity import ResourceEntity
from ..models.user_model import User, UserTypeEnum from ..models.user_model import User, UserTypeEnum, ProgramTypeEnum
from .exceptions import ProgramNotAssignedException, ResourceNotFoundException from .exceptions import ProgramNotAssignedException, ResourceNotFoundException
@ -129,21 +130,20 @@ class ResourceService:
) )
resource_entity.name = resource.name resource_entity.name = resource.name
resource_entity.status = resource.status
resource_entity.summary = resource.summary resource_entity.summary = resource.summary
resource_entity.requirements = resource.requirements
resource_entity.program = resource.program resource_entity.program = resource.program
resource_entity.link = resource.link
for tag in resource.tags: for tag in resource.tags:
tag_entity = self._tag_service.get_or_create_tag(tag.content) tag_entity = self._tag_service.get_or_create_tag(tag.content)
self._tag_service.add_tag_service( self._tag_service.add_tag_resource(
user, tag_entity, ResourceEntity.to_model(resource_entity) user, tag_entity, ResourceEntity.to_model(resource_entity)
) )
self._session.commit() self._session.commit()
return resource_entity.to_model() return resource_entity.to_model()
def delete(self, user: User, id: int) -> None: def delete(self, user: User, resource: Resource) -> None:
""" """
Delete resource based on id that the user has access to Delete resource based on id that the user has access to
@ -154,12 +154,17 @@ class ResourceService:
Raises: Raises:
ResourceNotFoundException: If no resource is found with the corresponding id ResourceNotFoundException: If no resource is found with the corresponding id
""" """
if user.role != UserTypeEnum.ADMIN:
raise ProgramNotAssignedException(
f"User is not {UserTypeEnum.ADMIN}, cannot delete service"
)
resource = ( resource = (
self._session.query(ResourceEntity) self._session.query(ResourceEntity)
.filter( .filter(
ResourceEntity.id == id, ResourceEntity.id == resource.id,
ResourceEntity.role == user.role, ResourceEntity.program.in_(user.program),
ResourceEntity.group == user.group,
) )
.one_or_none() .one_or_none()
) )
@ -184,11 +189,30 @@ class ResourceService:
Raises: Raises:
ResourceNotFoundException if no resource is found with the corresponding slug ResourceNotFoundException if no resource is found with the corresponding slug
""" """
query = select(ResourceEntity).where( query = select(ResourceEntity).filter(
ResourceEntity.title.ilike(f"%{search_string}%"), and_(
ResourceEntity.role == user.role, ResourceEntity.program.in_(user.program),
ResourceEntity.group == user.group, or_(
ResourceEntity.name.ilike(f"%{search_string}%"),
ResourceEntity.summary.ilike(f"%{search_string}%"),
),
)
) )
entities = self._session.scalars(query).all() entities = self._session.scalars(query).all()
return [entity.to_model() for entity in entities] return [entity.to_model() for entity in entities]
def get_by_program(self, user: User, program: ProgramTypeEnum):
if not user.program.__contains__(program):
raise ProgramNotAssignedException
query = select(ResourceEntity).where(ResourceEntity.program == program)
entities = self._session.scalars(query).all()
return [entity.to_model() for entity in entities]
def get_by_tag_id(self, tag_id: int) -> List[Resource]:
resource_ids = self._tag_service.get_all_resources_by_tagid(tag_id)
resources = []
for id in resource_ids:
resources.append(self.get_by_id(id))
return resources

View File

@ -6,7 +6,7 @@ from backend.entities.tag_entity import TagEntity
from ..database import db_session from ..database import db_session
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from sqlalchemy import func, select, and_, func, or_, exists, or_ from sqlalchemy import func, select, and_, func, or_, exists, or_, any_
from backend.models.service_model import Service from backend.models.service_model import Service
from backend.models.user_model import User from backend.models.user_model import User
@ -16,7 +16,7 @@ from backend.services.exceptions import (
ServiceNotFoundException, ServiceNotFoundException,
ProgramNotAssignedException, ProgramNotAssignedException,
) )
from . import TagService from backend.services.tag import TagService
from ..models import Tag from ..models import Tag
@ -56,14 +56,26 @@ class ServiceService:
raise ServiceNotFoundException(f"Service with name: {name} does not exist") raise ServiceNotFoundException(f"Service with name: {name} does not exist")
service = entity.to_model() service = entity.to_model()
# service.tags.extend(TagService.get_tags_for_service(TagService, service))
return service return service
def get_service_by_slug(self, search_str: str) -> List[Service]:
"""Service method getting services by slug."""
query = select(ServiceEntity).filter(
or_(
ServiceEntity.name.ilike(f"%{search_str}%"),
ServiceEntity.status.ilike(f"%{search_str}%"),
ServiceEntity.summary.ilike(f"%{search_str}%"),
any_(ServiceEntity.requirements).ilike(f"%{search_str}%"),
)
)
entity = self._session.scalars(query).all()
return [service.to_model() for service in entity]
def get_service_by_user(self, subject: User): def get_service_by_user(self, subject: User):
"""Service method getting all of the services that a user has access to based on role""" """Service method getting all of the services that a user has access to based on role"""
if subject.role != UserTypeEnum.VOLUNTEER: if subject.role != UserTypeEnum.VOLUNTEER:
query = select(ServiceEntity) entities = self._session.query(ServiceEntity).all()
entities = self._session.scalars(query).all()
return [service.to_model() for service in entities] return [service.to_model() for service in entities]
else: else:
@ -84,8 +96,7 @@ class ServiceService:
f"User is not {UserTypeEnum.ADMIN} or {UserTypeEnum.VOLUNTEER}, cannot get all" f"User is not {UserTypeEnum.ADMIN} or {UserTypeEnum.VOLUNTEER}, cannot get all"
) )
query = select(ServiceEntity) entities = self._session.query(ServiceEntity).all()
entities = self._session.scalars(query).all()
services = [service.to_model() for service in entities] services = [service.to_model() for service in entities]
return services return services
@ -157,27 +168,29 @@ class ServiceService:
raise ServiceNotFoundException( raise ServiceNotFoundException(
"The service you are searching for does not exist." "The service you are searching for does not exist."
) )
self._tag_service.delete_all_tags_service(service_entity.to_model()) if self._tag_service.get_tags_for_service(service).count(Tag) != 0:
self._tag_service.delete_all_tags_service(service)
self._session.delete(service_entity) self._session.delete(service_entity)
self._session.commit() self._session.commit()
def get_service_by_tag_id(self, tag_id: int) -> List[Service]:
service_ids = self._tag_service.get_all_services_by_tagid(tag_id)
services = []
for id in service_ids:
services.append(self.get_service_by_id(id))
return services
"""
Can be used, but both methods are achieved by update.
def add_tag(self, subject: User, service: Service, tag: Tag): def add_tag(self, subject: User, service: Service, tag: Tag):
service = self.get_service_by_id(service.id) service = self.get_service_by_id(service.id)
tag = self._tag_service.get_tag_by_id(tag.id) tag = self._tag_service.get_tag_by_id(tag.id)
self._tag_service.add_tag_service(subject, service.id, tag.id) self._tag_service.add_tag_service(subject, service.id, tag.id)
def remove_tag(self, subject: User, service: Service, tag: Tag) -> None: def remove_tag(self, subject: User, service: Service, tag: Tag) -> None:
service_tag = ( serviceEntity = self.get_service_by_id(service.id)
self._session.query(ServiceTagEntity) tagEntity = self._tag_service.get_tag_by_id(tag.id)
.filter( self._tag_service.delete_tag_service(subject, tagEntity, serviceEntity)
ServiceTagEntity.serviceId == service.id, """
ServiceTagEntity.tagId == tag.id,
)
.one_or_none()
)
if service_tag is None:
raise Exception(
f"No tag with id {tag.id} found for service with id {service.id}."
)
self._session.delete(service_tag)
self._session.commit()

View File

@ -1,3 +1,4 @@
from typing import List
from fastapi import Depends from fastapi import Depends
from backend.models.enum_for_models import UserTypeEnum from backend.models.enum_for_models import UserTypeEnum
@ -7,7 +8,6 @@ from sqlalchemy import select
from ..entities import TagEntity, ResourceTagEntity, ServiceTagEntity from ..entities import TagEntity, ResourceTagEntity, ServiceTagEntity
from ..models import User, Resource, Service, Tag, ResourceTag, ServiceTag from ..models import User, Resource, Service, Tag, ResourceTag, ServiceTag
from .exceptions import ProgramNotAssignedException, ResourceNotFoundException from .exceptions import ProgramNotAssignedException, ResourceNotFoundException
from datetime import datetime
class TagService: class TagService:
@ -140,6 +140,30 @@ class TagService:
self._session.rollback() # Rollback in case of error self._session.rollback() # Rollback in case of error
raise Exception("Failed to add tag to resource") from e raise Exception("Failed to add tag to resource") from e
def delete_tag_resource(self, user: User, tag: Tag, resource: Resource) -> None:
"""Deletes a tag from a service"""
existing_tag = (
self._session.query(ResourceTagEntity)
.filter(
ResourceTagEntity.tagId == tag.id,
ResourceTagEntity.resourceId == resource.id,
)
.first()
)
if existing_tag == None:
raise Exception(
f"Tag with id {tag.id} does not exist for resource with id {resource.id}."
)
try:
self._session.delete(existing_tag)
self._session.commit()
except Exception as e:
self._session.rollback() # Rollback in case of error
raise Exception("Failed to delete tag to service") from e
def add_tag_service(self, user: User, tag: Tag, service: Service) -> None: def add_tag_service(self, user: User, tag: Tag, service: Service) -> None:
"""Adds a tag to a service""" """Adds a tag to a service"""
@ -168,15 +192,41 @@ class TagService:
self._session.rollback() # Rollback in case of error self._session.rollback() # Rollback in case of error
raise Exception("Failed to add tag to service") from e raise Exception("Failed to add tag to service") from e
def delete_tag_service(self, user: User, tag: Tag, service: Service) -> None:
"""Deletes a tag from a service"""
existing_tag = (
self._session.query(ServiceTagEntity)
.filter(
ServiceTagEntity.tagId == tag.id,
ServiceTagEntity.serviceId == service.id,
)
.first()
)
if existing_tag == None:
raise Exception(
f"Tag with id {tag.id} does not exist for service with id {service.id}."
)
try:
self._session.delete(existing_tag)
self._session.commit()
except Exception as e:
self._session.rollback() # Rollback in case of error
raise Exception("Failed to delete tag to service") from e
def delete_all_tags_service(self, service: Service) -> None: def delete_all_tags_service(self, service: Service) -> None:
"""Deletes all service tags for a service""" """Deletes all service tags for a service"""
service_tags = self._session.query(ServiceTagEntity).filter( service_tags = (
ServiceTagEntity.serviceId == service.id self._session.query(ServiceTagEntity)
.filter(ServiceTagEntity.serviceId == service.id)
.all()
) )
if service_tags.count() == 0: if service_tags.count(ServiceTagEntity) == 0:
raise ResourceNotFoundException return
service_tags.delete(synchronize_session=False) service_tags.delete(synchronize_session=False)
self._session.commit() self._session.commit()
@ -184,12 +234,14 @@ class TagService:
def delete_all_tags_resource(self, resource: Resource) -> None: def delete_all_tags_resource(self, resource: Resource) -> None:
"""Deletes all resource tags for a resource""" """Deletes all resource tags for a resource"""
resource_tags = self._session.query(ResourceTagEntity).filter( resource_tags = (
ResourceTagEntity.resourceId == resource.id self._session.query(ResourceTagEntity)
.filter(ResourceTagEntity.resourceId == resource.id)
.all()
) )
if resource_tags.count() == 0: if resource_tags.count() == 0:
raise ResourceNotFoundException return
resource_tags.delete(synchronize_session=False) resource_tags.delete(synchronize_session=False)
self._session.commit() self._session.commit()
@ -213,3 +265,21 @@ class TagService:
except Exception as e: except Exception as e:
self._session.rollback() self._session.rollback()
raise Exception(f"Failed to create tag with content: {tag.content}") from e raise Exception(f"Failed to create tag with content: {tag.content}") from e
def get_all_services_by_tagid(self, tagId: int) -> List[int]:
services = (
self._session.query(ServiceTagEntity)
.filter(ServiceTagEntity.tagId == tagId)
.all()
)
return [service.serviceId for service in services]
def get_all_resources_by_tagid(self, tagId: int) -> List[int]:
resources = (
self._session.query(ResourceTagEntity)
.filter(ResourceTagEntity.tagId == tagId)
.all()
)
return [resource.resourceId for resource in resources]

View File

@ -14,6 +14,7 @@ from .services import (
from ..database import _engine_str from ..database import _engine_str
from ..env import getenv from ..env import getenv
from .. import entities from .. import entities
from ..services import TagService
POSTGRES_DATABASE = f'{getenv("POSTGRES_DATABASE")}_test' POSTGRES_DATABASE = f'{getenv("POSTGRES_DATABASE")}_test'
POSTGRES_USER = getenv("POSTGRES_USER") POSTGRES_USER = getenv("POSTGRES_USER")
@ -65,3 +66,9 @@ def setup_insert_data_fixture(session: Session):
resource_test_data.insert_fake_data(session) resource_test_data.insert_fake_data(session)
session.commit() session.commit()
yield yield
@pytest.fixture()
def tag_svc(session: Session):
"""This fixture is used to test the TagService class"""
return TagService(session)

View File

@ -13,18 +13,12 @@ def user_svc(session: Session):
@pytest.fixture() @pytest.fixture()
def tag_svc(session: Session): def service_svc(session: Session, tag_svc: TagService):
"""This fixture is used to test the TagService class"""
return TagService(session)
@pytest.fixture()
def service_svc(session: Session):
"""This fixture is used to test the ServiceService class""" """This fixture is used to test the ServiceService class"""
return ServiceService(session) return ServiceService(session, tag_svc)
@pytest.fixture() @pytest.fixture()
def resource_svc(session: Session): def resource_svc(session: Session, tag_svc: TagService):
"""This fixutre is used to test the ResourceService class""" """This fixutre is used to test the ResourceService class"""
return ResourceService(session) return ResourceService(session, tag_svc)

View File

@ -1,6 +1,12 @@
from backend.models.enum_for_models import ProgramTypeEnum
from backend.models.resource_model import Resource
from backend.models.tag_model import Tag
from backend.services import ResourceService, TagService from backend.services import ResourceService, TagService
from backend.services.exceptions import ResourceNotFoundException
from .user_test_data import admin from .user_test_data import admin
from .fixtures import resource_svc, tag_svc from .fixtures import resource_svc
from backend.test.services import user_test_data, resource_test_data, tag_test_data
import pytest
def test_temp(resource_svc: ResourceService, tag_svc: TagService): def test_temp(resource_svc: ResourceService, tag_svc: TagService):
@ -8,3 +14,99 @@ def test_temp(resource_svc: ResourceService, tag_svc: TagService):
tags = tag_svc.all() tags = tag_svc.all()
print(tags) print(tags)
print(resources) print(resources)
def test_list(resource_svc: ResourceService):
resource = resource_svc.get_resource_by_user(user_test_data.admin)
assert len(resource) == len(resource_test_data.resources)
assert isinstance(resource[0], Resource)
def test_get_by_name(resource_svc: ResourceService):
resource = resource_svc.get_by_slug(user_test_data.admin, "resource 1")
assert resource[0].name == resource_test_data.resource1.name
assert isinstance(resource[0], Resource)
def test_get_by_name_not_found(resource_svc: ResourceService):
resource = resource_svc.get_by_slug(user_test_data.admin, "resource 12")
assert len(resource) == 0
def test_get_resource_by_user_admin(resource_svc: ResourceService):
resource = resource_svc.get_resource_by_user(user_test_data.admin)
assert len(resource) == len(resource_test_data.resources)
def test_get_resource_by_user_volun(resource_svc: ResourceService):
resource = resource_svc.get_resource_by_user(user_test_data.volunteer)
assert len(resource) == 2
def test_get_by_program(resource_svc: ResourceService):
resources = resource_svc.get_by_program(
user_test_data.admin, ProgramTypeEnum.COMMUNITY
)
for resource in resources:
assert resource.program == ProgramTypeEnum.COMMUNITY
assert isinstance(resource, Resource)
def test_create(resource_svc: ResourceService):
resource = resource_svc.create(
user_test_data.admin, resource_test_data.resource_to_create
)
assert resource.name == resource_test_data.resource_to_create.name
assert isinstance(resource, Resource)
def test_update(resource_svc: ResourceService):
resource = resource_svc.update(
user_test_data.admin, resource_test_data.resource4_edit
)
assert resource.name == resource_test_data.resource4_edit.name
assert isinstance(resource, Resource)
def test_update_with_tags(resource_svc: ResourceService):
resource = resource_svc.update(user_test_data.admin, resource_test_data.resource2)
assert len(resource.tags) == 2
def test_update_not_found(resource_svc: ResourceService):
with pytest.raises(ResourceNotFoundException):
resource = resource_svc.update(
user_test_data.admin, resource_test_data.resource_to_create
)
pytest.fail()
def test_delete(resource_svc: ResourceService):
resource_svc.delete(user_test_data.admin, resource_test_data.resource3)
resources = resource_svc.get_resource_by_user(user_test_data.admin)
assert len(resources) == len(resource_test_data.resources) - 1
def test_delete_not_found(resource_svc: ResourceService):
with pytest.raises(ResourceNotFoundException):
resource_svc.delete(user_test_data.admin, resource_test_data.resource_10)
pytest.fail()
def test_create_resource_with_tags(resource_svc: ResourceService):
resource = Resource(
name="test resource",
summary="summary",
link="www.example.com",
program=ProgramTypeEnum.COMMUNITY,
tags=[Tag(content="resource tag")],
)
resource_entity = resource_svc.create(user_test_data.admin, resource)
assert len(resource_entity.tags) == 1
def test_update_tags_for_resource(resource_svc: ResourceService):
resourceEntity = resource_svc.update(
user_test_data.admin, resource_test_data.resource2_edit_tags
)
assert len(resourceEntity.tags) == 1

View File

@ -4,6 +4,7 @@ from datetime import datetime
from ...entities import ResourceEntity from ...entities import ResourceEntity
from ...models.enum_for_models import ProgramTypeEnum from ...models.enum_for_models import ProgramTypeEnum
from ...models.resource_model import Resource from ...models.resource_model import Resource
from .tag_test_data import *
resource1 = Resource( resource1 = Resource(
id=1, id=1,
@ -20,7 +21,16 @@ resource2 = Resource(
summary="Legal assistance resources", summary="Legal assistance resources",
link="https://example.com/resource2", link="https://example.com/resource2",
program=ProgramTypeEnum.COMMUNITY, program=ProgramTypeEnum.COMMUNITY,
created_at=datetime(2023, 6, 2, 12, 30, 0), tags=[tag1, tag2],
)
resource2_edit_tags = Resource(
id=2,
name="Resource 2",
summary="Legal assistance resources",
link="https://example.com/resource2",
program=ProgramTypeEnum.COMMUNITY,
tags=[tag2],
) )
resource3 = Resource( resource3 = Resource(
@ -41,6 +51,15 @@ resource4 = Resource(
created_at=datetime(2023, 6, 4, 9, 15, 0), created_at=datetime(2023, 6, 4, 9, 15, 0),
) )
resource4_edit = Resource(
id=4,
name="Resource 4 edited",
summary="Counseling and support groups",
link="https://example.com/resource4",
program=ProgramTypeEnum.DOMESTIC,
created_at=datetime(2023, 6, 4, 9, 15, 0),
)
resource5 = Resource( resource5 = Resource(
id=5, id=5,
name="Resource 5", name="Resource 5",
@ -50,6 +69,13 @@ resource5 = Resource(
created_at=datetime(2023, 6, 5, 11, 30, 0), created_at=datetime(2023, 6, 5, 11, 30, 0),
) )
resource_to_create = Resource(
name="Created Resource",
summary="Resource Test Create",
link="https://example.com/",
program=ProgramTypeEnum.COMMUNITY,
)
resources = [resource1, resource2, resource3, resource4, resource5] resources = [resource1, resource2, resource3, resource4, resource5]
resource_1 = Resource( resource_1 = Resource(

View File

@ -1,3 +1,4 @@
from backend.models.tag_model import Tag
from backend.models.user_model import User from backend.models.user_model import User
from backend.entities.service_entity import ServiceEntity from backend.entities.service_entity import ServiceEntity
from ...models.enum_for_models import ProgramTypeEnum from ...models.enum_for_models import ProgramTypeEnum
@ -5,6 +6,7 @@ from backend.services.service import ServiceService
from backend.services.exceptions import ServiceNotFoundException from backend.services.exceptions import ServiceNotFoundException
from . import service_test_data from . import service_test_data
from . import user_test_data from . import user_test_data
from . import tag_test_data
from .fixtures import service_svc, user_svc from .fixtures import service_svc, user_svc
from backend.models.service_model import Service from backend.models.service_model import Service
import pytest import pytest
@ -58,6 +60,11 @@ def test_update(service_svc: ServiceService):
assert isinstance(service, Service) assert isinstance(service, Service)
def test_update_with_tags(service_svc: ServiceService):
service = service_svc.update(user_test_data.admin, service_test_data.service2)
assert len(service.tags) == 2
def test_update_not_found(service_svc: ServiceService): def test_update_not_found(service_svc: ServiceService):
with pytest.raises(ServiceNotFoundException): with pytest.raises(ServiceNotFoundException):
service = service_svc.update( service = service_svc.update(
@ -72,7 +79,37 @@ def test_delete(service_svc: ServiceService):
assert len(services) == len(service_test_data.services) - 1 assert len(services) == len(service_test_data.services) - 1
"""def test_delete_not_found(service_svc: ServiceService): def test_delete_not_found(service_svc: ServiceService):
with pytest.raises(ServiceNotFoundException): with pytest.raises(ServiceNotFoundException):
service_svc.delete(user_test_data.admin, service_test_data.service_10) service_svc.delete(user_test_data.admin, service_test_data.service_10)
pytest.fail()""" pytest.fail()
def test_create_service_with_tags(service_svc: ServiceService):
service = Service(
name="test service",
status="open",
summary="summary",
requirements=["18 years or older"],
program=ProgramTypeEnum.COMMUNITY,
tags=[Tag(content="service tag")],
)
service_entity = service_svc.create(user_test_data.admin, service)
assert len(service_entity.tags) == 1
def test_update_tags_for_service(service_svc: ServiceService):
serviceEntity = service_svc.update(
user_test_data.admin, service_test_data.service2_update
)
assert len(serviceEntity.tags) == 2
def test_get_service_by_slug(service_svc: ServiceService):
services = service_svc.get_service_by_slug("service 1")
assert services[0].id == service_test_data.service1.id
def test_get_service_by_requirements_slug(service_svc: ServiceService):
services = service_svc.get_service_by_slug("safe places to stay")
assert services[0].id == service_test_data.service2.id

View File

@ -4,7 +4,7 @@ from sqlalchemy.orm import Session
from ...entities import ServiceEntity from ...entities import ServiceEntity
from ...models.enum_for_models import ProgramTypeEnum from ...models.enum_for_models import ProgramTypeEnum
from ...models import Service, Tag from ...models import Service, Tag
from .tag_test_data import tags from .tag_test_data import *
service1 = Service( service1 = Service(
id=1, id=1,
@ -13,6 +13,7 @@ service1 = Service(
summary="presentation educating community on domestic violence", summary="presentation educating community on domestic violence",
requirements=[""], requirements=[""],
program=ProgramTypeEnum.COMMUNITY, program=ProgramTypeEnum.COMMUNITY,
tags=[tag1],
) )
service2 = Service( service2 = Service(
@ -22,6 +23,17 @@ service2 = Service(
summary="service finding safe places to stay", summary="service finding safe places to stay",
requirements=[""], requirements=[""],
program=ProgramTypeEnum.DOMESTIC, program=ProgramTypeEnum.DOMESTIC,
tags=[tag1, tag2],
)
service2_update = Service(
id=2,
name="service 2",
status="closed",
summary="service finding safe places to stay",
requirements=[""],
program=ProgramTypeEnum.DOMESTIC,
tags=[tag1, tag_to_create],
) )
service3 = Service( service3 = Service(
@ -31,6 +43,7 @@ service3 = Service(
summary="", summary="",
requirements=[""], requirements=[""],
program=ProgramTypeEnum.DOMESTIC, program=ProgramTypeEnum.DOMESTIC,
tags=[tags[0], tags[1], tags[2]],
) )
service4 = Service( service4 = Service(
@ -40,6 +53,7 @@ service4 = Service(
summary="community event", summary="community event",
requirements=[""], requirements=[""],
program=ProgramTypeEnum.COMMUNITY, program=ProgramTypeEnum.COMMUNITY,
tags=[Tag(content="Tag 4"), Tag(content="Tag 1")],
) )
service5 = Service( service5 = Service(
@ -49,6 +63,7 @@ service5 = Service(
summary="talk circle for victims of domestic violence", summary="talk circle for victims of domestic violence",
requirements=["18+"], requirements=["18+"],
program=ProgramTypeEnum.COMMUNITY, program=ProgramTypeEnum.COMMUNITY,
tags=[Tag(content="Tag 5")],
) )
service6 = Service( service6 = Service(
@ -58,6 +73,7 @@ service6 = Service(
summary="program offering economic assistance", summary="program offering economic assistance",
requirements=[""], requirements=[""],
program=ProgramTypeEnum.ECONOMIC, program=ProgramTypeEnum.ECONOMIC,
tags=[Tag(content="Tag 6")],
) )
service_6_edit = Service( service_6_edit = Service(
@ -76,6 +92,7 @@ service7 = Service(
summary="insert generic description", summary="insert generic description",
requirements=[""], requirements=[""],
program=ProgramTypeEnum.ECONOMIC, program=ProgramTypeEnum.ECONOMIC,
tags=[Tag(content="Tag 7")],
) )
new_service = Service( new_service = Service(