Skip to content

Commit

Permalink
Merge pull request #3 from fga-eps-mds/8-favoritarVideo
Browse files Browse the repository at this point in the history
 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
victorleaoo authored Aug 6, 2024
2 parents bc6ec59 + 06c5b24 commit a04e209
Show file tree
Hide file tree
Showing 44 changed files with 339 additions and 3 deletions.
Empty file modified .github/templates/bug_report.md
100644 → 100755
Empty file.
Empty file modified .github/templates/feature_request.md
100644 → 100755
Empty file.
Empty file modified .github/templates/pull_request_template.md
100644 → 100755
Empty file.
Empty file modified .github/templates/user_stories.md
100644 → 100755
Empty file.
Empty file modified .github/workflows/code-analysis.yml
100644 → 100755
Empty file.
Empty file modified .github/workflows/deploy.yml
100644 → 100755
Empty file.
Empty file modified .github/workflows/release.yml
100644 → 100755
Empty file.
Empty file modified .gitignore
100644 → 100755
Empty file.
Empty file modified Dockerfile
100644 → 100755
Empty file.
Empty file modified LICENSE
100644 → 100755
Empty file.
Empty file modified Procfile
100644 → 100755
Empty file.
Empty file modified README.md
100644 → 100755
Empty file.
Empty file modified docker-compose.yml
100644 → 100755
Empty file.
Empty file modified env.example
100644 → 100755
Empty file.
Empty file modified requirements.txt
100644 → 100755
Empty file.
Empty file modified runtime.txt
100644 → 100755
Empty file.
Empty file modified sonar-project.properties
100644 → 100755
Empty file.
Empty file modified sonar_scripts/parser.py
100644 → 100755
Empty file.
Empty file modified src/__init__.py
100644 → 100755
Empty file.
Empty file modified src/constants/__init__.py
100644 → 100755
Empty file.
Empty file modified src/constants/errorMessages.py
100644 → 100755
Empty file.
Empty file modified src/controller/__init__.py
100644 → 100755
Empty file.
Empty file modified src/controller/commentController.py
100644 → 100755
Empty file.
50 changes: 50 additions & 0 deletions src/controller/savedVideosController.py
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 modified src/controller/scheduleController.py
100644 → 100755
Empty file.
10 changes: 9 additions & 1 deletion src/database.py
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,12 @@ def get_db():
try:
yield db
finally:
db.close()
db.close()

# Função para inicializar o banco de dados
def init_db():
Base.metadata.create_all(bind=engine)


# Inicializa o banco de dados ao importar este módulo
init_db()
Empty file modified src/domain/__init__.py
100644 → 100755
Empty file.
Empty file modified src/domain/commentSchema.py
100644 → 100755
Empty file.
21 changes: 21 additions & 0 deletions src/domain/savedVideosSchema.py
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
15 changes: 13 additions & 2 deletions src/main.py
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@
from fastapi import FastAPI
from dotenv import load_dotenv
from fastapi.middleware.cors import CORSMiddleware
from database import init_db # Adicione a função de inicialização do banco de dados



load_dotenv()

from controller import commentController, scheduleController
from controller import commentController, scheduleController, savedVideosController
from controller.savedVideosController import WatchLater


# Desativado os os comentarios nos videos
# from database import SessionLocal, engine
Expand All @@ -25,8 +30,14 @@
allow_headers=["*"],
)

# app.include_router(prefix="/api", router=commentController.comment)
# Inicializar o banco de dados
init_db()


app.include_router(WatchLater, prefix="/api")
#app.include_router(prefix="/api", router=commentController.comment)
app.include_router(prefix="/api", router=scheduleController.schedule)
app.include_router(prefix="/api", router=savedVideosController.favorite)

@app.get("/")
async def root():
Expand Down
Empty file modified src/model/__init__.py
100644 → 100755
Empty file.
Empty file modified src/model/commentModel.py
100644 → 100755
Empty file.
12 changes: 12 additions & 0 deletions src/model/savedVideosModel.py
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 modified src/repository/__init__.py
100644 → 100755
Empty file.
Empty file modified src/repository/commentRepository.py
100644 → 100755
Empty file.
101 changes: 101 additions & 0 deletions src/repository/savedVideosRepository.py
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 modified src/utils/enumeration.py
100644 → 100755
Empty file.
Empty file modified tests/__init__.py
100644 → 100755
Empty file.
Empty file modified tests/_test_comments.py
100644 → 100755
Empty file.
1 change: 1 addition & 0 deletions tests/junit.xml
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 added tests/test.db
Empty file.
66 changes: 66 additions & 0 deletions tests/test_favorite.py
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 modified tests/test_schedule.py
100644 → 100755
Empty file.
66 changes: 66 additions & 0 deletions tests/test_watch_later.py
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

0 comments on commit a04e209

Please sign in to comment.