forked from UnBTV/UnB-TV-VideoService
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3 from fga-eps-mds/8-favoritarVideo
US08 - Eu, como usuário, quero favoritar um vídeo diretamente da página de visualização, para acessá-lo facilmente depois. + US13 - Eu, como usuário, quero marcar vídeos para assistir mais tarde
- Loading branch information
Showing
44 changed files
with
339 additions
and
3 deletions.
There are no files selected for viewing
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
from fastapi import APIRouter, HTTPException, Depends, Query | ||
from sqlalchemy.orm import Session | ||
from domain import savedVideosSchema | ||
from database import get_db | ||
from repository import savedVideosRepository | ||
from starlette.responses import JSONResponse | ||
|
||
WatchLater = APIRouter( | ||
prefix="/watch-later" | ||
) | ||
|
||
@WatchLater.post("/") | ||
def add_to_watch_later(watch_later: savedVideosSchema.WatchLaterCreate, db: Session = Depends(get_db)): | ||
return savedVideosRepository.create_watch_later(db=db, watch_later=watch_later) | ||
|
||
|
||
@WatchLater.delete("/{video_id}") | ||
def remove_from_watch_later(video_id: str, user_id: str = Query(...), db: Session = Depends(get_db)): | ||
user_id = user_id.strip() | ||
video_id = video_id.strip() | ||
savedVideosRepository.remove_watch_later(db=db, video_id=video_id, user_id=user_id) | ||
return {"message": "Removed from watch later list"} | ||
|
||
|
||
@WatchLater.get("/status/{video_id}") | ||
def check_watch_later(video_id: str, user_id: str = Query(...), db: Session = Depends(get_db)): | ||
status = savedVideosRepository.check_watch_later_status(db=db, video_id=video_id, user_id=user_id) | ||
return {"status": status} | ||
|
||
# início das requisições do favorite | ||
|
||
favorite = APIRouter( | ||
prefix="/favorite" | ||
) | ||
|
||
@favorite.post("/") | ||
def add_to_favorite(favorite: savedVideosSchema.FavoriteCreate, db: Session = Depends(get_db)): | ||
return savedVideosRepository.create_favorite(db=db, favorite=favorite) | ||
|
||
@favorite.get("/status/{video_id}") | ||
def check_favorite(video_id: str, user_id: str = Query(...), db: Session = Depends(get_db)): | ||
status = savedVideosRepository.check_favorite_status(db=db, video_id=video_id, user_id=user_id) | ||
return status | ||
|
||
@favorite.delete("/{video_id}") | ||
def remove_from_favorites(video_id: str, user_id: str = Query(...), db: Session = Depends(get_db)): | ||
user_id = user_id.strip() | ||
video_id = video_id.strip() | ||
savedVideosRepository.remove_favorite(db=db, video_id=video_id, user_id=user_id) | ||
return {"message": "Removed from favorites"} |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
from pydantic import BaseModel | ||
|
||
class WatchLaterBase(BaseModel): | ||
user_id: str | ||
video_id: str | ||
|
||
class WatchLaterCreate(WatchLaterBase): | ||
pass | ||
|
||
class WatchLaterStatus(WatchLaterBase): | ||
staus: bool | ||
|
||
class FavoriteBase(BaseModel): | ||
user_id: str | ||
video_id: str | ||
|
||
class FavoriteCreate(FavoriteBase): | ||
pass | ||
|
||
class FavoriteStatus(FavoriteBase): | ||
status: bool |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import uuid | ||
from sqlalchemy import Column, String, Boolean | ||
from database import Base | ||
|
||
class WatchLater(Base): | ||
__tablename__ = 'watch_later' | ||
id = Column(String, primary_key=True, index=True, default=lambda: str(uuid.uuid4())) | ||
user_id = Column(String, index=True, nullable=False) | ||
video_id = Column(String, index=True, nullable=False) | ||
status = Column(Boolean, default=False) #assistir mais tarde | ||
statusfavorite = Column(Boolean, default=False) # favoritos | ||
|
Empty file.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
from sqlalchemy.orm import Session | ||
|
||
from domain import savedVideosSchema | ||
from model import savedVideosModel | ||
from fastapi import HTTPException | ||
|
||
def create_watch_later(db: Session, watch_later: savedVideosSchema.WatchLaterCreate): | ||
db_watch_later = savedVideosModel.WatchLater( | ||
user_id=watch_later.user_id.strip(), | ||
video_id=watch_later.video_id.strip(), | ||
status=True | ||
) | ||
db.add(db_watch_later) | ||
db.commit() | ||
db.refresh(db_watch_later) | ||
print(f"Created watchLater: user_id={db_watch_later.user_id}, video_id={db_watch_later.video_id}, id={db_watch_later.id}, status={db_watch_later.status}") | ||
return db_watch_later | ||
|
||
|
||
def remove_watch_later(db: Session, video_id: str, user_id: str): | ||
video_id = video_id.strip() | ||
user_id = user_id.strip() | ||
print(f"Removing video_id={video_id} for user_id={user_id}") | ||
watch_later_entry = db.query(savedVideosModel.WatchLater).filter( | ||
savedVideosModel.WatchLater.video_id == video_id, | ||
savedVideosModel.WatchLater.user_id == user_id, | ||
savedVideosModel.WatchLater.status == True | ||
).first() | ||
print(f"Query Result: {watch_later_entry}") | ||
if watch_later_entry: | ||
db.delete(watch_later_entry) | ||
db.commit() | ||
print(f"Removed WatchLater: user_id={user_id}, video_id={video_id}") | ||
return {"message": "Removed from watch later list"} | ||
else: | ||
raise HTTPException(status_code=404, detail="Video not found in watch later list") | ||
|
||
|
||
def check_watch_later_status(db: Session, video_id: str, user_id: str) -> bool: | ||
video_id = video_id.strip() | ||
user_id = user_id.strip() | ||
print(f"Executing Query: video_id={video_id}, user_id={user_id}") | ||
watch_later_entry = db.query(savedVideosModel.WatchLater).filter( | ||
savedVideosModel.WatchLater.video_id == video_id, | ||
savedVideosModel.WatchLater.user_id == user_id, | ||
savedVideosModel.WatchLater.status == True | ||
).first() | ||
print(f"Query Result: {watch_later_entry}") | ||
if watch_later_entry: | ||
print(f"Check Watch Later Status: video_id={video_id}, user_id={user_id}, status={watch_later_entry.status}") | ||
return watch_later_entry.status | ||
print(f"Check Watch Later Status: video_id={video_id}, user_id={user_id}, found=False") | ||
return False | ||
|
||
# início dos métodos do favorite | ||
|
||
def create_favorite(db: Session, favorite: savedVideosSchema.FavoriteCreate): | ||
db_favorite = savedVideosModel.WatchLater( | ||
user_id = favorite.user_id.strip(), | ||
video_id = favorite.video_id.strip(), | ||
statusfavorite = True | ||
) | ||
db.add(db_favorite) | ||
db.commit() | ||
db.refresh(db_favorite) | ||
return db_favorite | ||
|
||
def check_favorite_status(db: Session, video_id: str, user_id: str) -> dict: | ||
video_id = video_id.strip() | ||
user_id = user_id.strip() | ||
favorite_entry = db.query(savedVideosModel.WatchLater).filter( | ||
savedVideosModel.WatchLater.user_id == user_id, | ||
savedVideosModel.WatchLater.video_id == video_id, | ||
savedVideosModel.WatchLater.statusfavorite == True | ||
).first() | ||
if favorite_entry: | ||
return { | ||
"statusfavorite": favorite_entry.statusfavorite | ||
} | ||
return { | ||
"statusfavorite": False | ||
} | ||
|
||
def remove_favorite(db: Session, video_id: str, user_id: str): | ||
video_id = video_id.strip() | ||
user_id = user_id.strip() | ||
print(f"Removing favorite video_id={video_id} for user_id={user_id}") | ||
favorite_entry = db.query(savedVideosModel.WatchLater).filter( | ||
savedVideosModel.WatchLater.video_id == video_id, | ||
savedVideosModel.WatchLater.user_id == user_id, | ||
savedVideosModel.WatchLater.statusfavorite == True | ||
).first() | ||
print(f"Query Result: {favorite_entry}") | ||
if favorite_entry: | ||
db.delete(favorite_entry) | ||
db.commit() | ||
print(f"Removed Favorite: user_id={user_id}, video_id={video_id}") | ||
return {"message": "Removed from favorites"} | ||
else: | ||
raise HTTPException(status_code=404, detail="Video not found in favorites") | ||
|
Empty file.
Empty file.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
<?xml version="1.0" encoding="utf-8"?><testsuites><testsuite name="pytest" errors="0" failures="0" skipped="0" tests="10" time="2.535" timestamp="2024-08-05T02:33:42.345505" hostname="eb7d7d6cc578"><testcase classname="test_favorite" name="test_add_to_favorite" time="0.044" /><testcase classname="test_favorite" name="test_check_favorite" time="0.007" /><testcase classname="test_favorite" name="test_remove_from_favorites" time="0.012" /><testcase classname="test_schedule.TestSchedule" name="test_schedule_get_schedule_day" time="0.842" /><testcase classname="test_schedule.TestSchedule" name="test_schedule_get_schedule_specific_day_invalid" time="0.003" /><testcase classname="test_schedule.TestSchedule" name="test_schedule_get_schedule_specific_day" time="0.562" /><testcase classname="test_schedule.TestSchedule" name="test_schedule_get_schedule_day_exception_handling" time="0.005" /><testcase classname="test_watch_later" name="test_add_to_watch_later" time="0.011" /><testcase classname="test_watch_later" name="test_check_watch_later_status" time="0.006" /><testcase classname="test_watch_later" name="test_remove_from_watch_later" time="0.012" /></testsuite></testsuites> |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import pytest, sys, os | ||
|
||
|
||
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'src'))) | ||
|
||
|
||
from fastapi.testclient import TestClient | ||
from sqlalchemy import create_engine | ||
from sqlalchemy.orm import sessionmaker | ||
from src.database import Base, get_db | ||
from src.main import app | ||
|
||
|
||
# Crie um banco de dados de teste em memória | ||
SQLALCHEMY_DATABASE_URL = "sqlite:///./test.db" | ||
engine = create_engine(SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False}) | ||
TestingSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) | ||
|
||
|
||
# Dependência para usar o banco de dados de teste | ||
def override_get_db(): | ||
try: | ||
db = TestingSessionLocal() | ||
yield db | ||
finally: | ||
db.close() | ||
|
||
|
||
app.dependency_overrides[get_db] = override_get_db | ||
|
||
|
||
client = TestClient(app) | ||
|
||
|
||
@pytest.fixture(scope="module") | ||
def setup_database(): | ||
Base.metadata.create_all(bind=engine) | ||
yield | ||
Base.metadata.drop_all(bind=engine) | ||
|
||
|
||
def test_add_to_favorite(setup_database): | ||
response = client.post("/api/favorite/", json={"user_id": "user123", "video_id": "video123"}) | ||
assert response.status_code == 200 | ||
assert response.json()["user_id"] == "user123" | ||
assert response.json()["video_id"] == "video123" | ||
assert response.json()["statusfavorite"] is True | ||
|
||
def test_check_favorite(setup_database): | ||
response = client.get("/api/favorite/status/video123?user_id=user123") | ||
print(response.json()) | ||
assert response.status_code == 200 | ||
assert response.json()["statusfavorite"] is True | ||
|
||
def test_remove_from_favorites(setup_database): | ||
response = client.delete("/api/favorite/video123?user_id=user123") | ||
print("Response from DELETE:", response.json()) | ||
assert response.status_code == 200 | ||
assert response.json()["message"] == "Removed from favorites" | ||
|
||
|
||
# Check status again to ensure it's removed | ||
response = client.get("/api/favorite/status/video123?user_id=user123") | ||
print("Response from GET status:", response.json()) | ||
assert response.status_code == 200 | ||
assert response.json()["statusfavorite"] is False |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import pytest, sys, os | ||
|
||
|
||
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'src'))) | ||
|
||
|
||
from fastapi.testclient import TestClient | ||
from sqlalchemy import create_engine | ||
from sqlalchemy.orm import sessionmaker | ||
from src.database import Base, get_db | ||
from src.main import app | ||
|
||
|
||
# Crie um banco de dados de teste em memória | ||
SQLALCHEMY_DATABASE_URL = "sqlite:///./test.db" | ||
engine = create_engine(SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False}) | ||
TestingSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) | ||
|
||
|
||
# Dependência para usar o banco de dados de teste | ||
def override_get_db(): | ||
try: | ||
db = TestingSessionLocal() | ||
yield db | ||
finally: | ||
db.close() | ||
|
||
|
||
app.dependency_overrides[get_db] = override_get_db | ||
|
||
|
||
client = TestClient(app) | ||
|
||
|
||
@pytest.fixture(scope="module") | ||
def setup_database(): | ||
Base.metadata.create_all(bind=engine) | ||
yield | ||
Base.metadata.drop_all(bind=engine) | ||
|
||
|
||
def test_add_to_watch_later(setup_database): | ||
response = client.post("/api/watch-later/", json={"user_id": "user123", "video_id": "video123"}) | ||
assert response.status_code == 200 | ||
assert response.json()["user_id"] == "user123" | ||
assert response.json()["video_id"] == "video123" | ||
assert response.json()["status"] is True | ||
|
||
|
||
|
||
def test_check_watch_later_status(setup_database): | ||
response = client.get("/api/watch-later/status/video123?user_id=user123") | ||
assert response.status_code == 200 | ||
assert response.json()["status"] is True | ||
|
||
|
||
def test_remove_from_watch_later(setup_database): | ||
response = client.delete("/api/watch-later/video123?user_id=user123") | ||
assert response.status_code == 200 | ||
assert response.json()["message"] == "Removed from watch later list" | ||
|
||
|
||
# Check status again to ensure it's removed | ||
response = client.get("/api/watch-later/status/video123?user_id=user123") | ||
assert response.status_code == 200 | ||
assert response.json()["status"] is False |