Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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 #3

Merged
merged 13 commits into from
Aug 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading