Implemented bulk upload by passing a json structure. Added delete all channels, groups and priorities
All checks were successful
AWS Deploy on Push / build (push) Successful in 2m17s

This commit is contained in:
2025-06-12 18:49:20 -05:00
parent b8ac25e301
commit abb467749b
11 changed files with 630 additions and 11 deletions

View File

@@ -1,10 +1,8 @@
import uuid
from datetime import datetime, timezone
from unittest.mock import patch
import pytest
from fastapi import status
from fastapi.testclient import TestClient
from sqlalchemy import String
from sqlalchemy.orm import Session
from app.auth.dependencies import get_current_user
@@ -338,7 +336,69 @@ def test_update_channel_forbidden_for_non_admin(
assert "required roles" in response.json()["detail"]
# --- Test Cases For Delete Channel ---
# --- Test Cases For Delete Channels ---
def test_delete_all_channels_success(db_session, admin_user_client):
"""Test reset channels endpoint"""
# Create test data
create_mock_priorities_and_group(db_session, [(100, "High")], "Test Group")
channel_data = [
{
"name": "Channel 1",
"group-title": "Group A",
"tvg-id": "channel1.tv",
"tvg-name": "Channel One",
"tvg-logo": "logo1.png",
"urls": ["http://stream1.com", "http://backup1.com"],
}
]
admin_user_client.post("/channels/bulk-upload", json=channel_data)
# Verify data exists
assert db_session.query(MockChannelDB).count() == 1
assert db_session.query(MockChannelURL).count() == 2
# Reset channels
response = admin_user_client.delete("/channels")
assert response.status_code == status.HTTP_200_OK
assert response.json()["deleted"] == 1
# Verify data is gone
assert db_session.query(MockChannelDB).count() == 0
assert db_session.query(MockChannelURL).count() == 0
def test_delete_all_channels_forbidden_for_non_admin(db_session, non_admin_user_client):
"""Test delete all channels requires admin role"""
response = non_admin_user_client.delete("/channels")
assert response.status_code == status.HTTP_403_FORBIDDEN
def test_delete_all_channels_error_handling(db_session, admin_user_client):
"""Test error handling when deleting channels fails"""
# Create some test data
group_id = create_mock_priorities_and_group(
db_session, [(100, "High")], "Error Group"
)
channel = MockChannelDB(
name="Error Channel",
group_id=group_id,
tvg_id="error.tv",
urls=[MockChannelURL(url="http://error.com/stream", priority_id=100)],
)
db_session.add(channel)
db_session.commit()
# To test the error handling of the endpoint, we need to simulate a failure
# during the database operation. We patch the 'commit' method of the session
# class to raise an exception. This patch will be active during the API call.
with patch.object(
type(db_session), "commit", side_effect=Exception("Mock database commit error")
):
response = admin_user_client.delete("/channels/")
assert response.status_code == status.HTTP_500_INTERNAL_SERVER_ERROR
assert "Failed to delete channels" in response.json()["detail"]
def test_delete_channel_success(db_session: Session, admin_user_client: TestClient):
@@ -1275,3 +1335,254 @@ def test_list_channel_urls_forbidden_for_non_admin(
assert response.status_code == status.HTTP_403_FORBIDDEN
assert "required roles" in response.json()["detail"]
# --- Test Cases For Bulk Upload Channels ---
def test_bulk_upload_channels_success(
db_session: Session, admin_user_client: TestClient
):
"""Test successful bulk upload of channels"""
# Create priorities
priorities = [(100, "High"), (200, "Medium"), (300, "Low")]
for id, desc in priorities:
db_session.add(MockPriority(id=id, description=desc))
db_session.commit()
# Test data matching channels.json format
channels = [
{
"name": "Channel 1",
"group-title": "Group A",
"tvg-id": "channel1.tv",
"tvg-name": "Channel One",
"tvg-logo": "logo1.png",
"urls": ["http://stream1.com", "http://backup1.com"],
},
{
"name": "Channel 2",
"group-title": "Group B",
"tvg-id": "channel2.tv",
"tvg-name": "Channel Two",
"tvg-logo": "logo2.png",
"urls": ["http://stream2.com"],
},
]
response = admin_user_client.post("/channels/bulk-upload", json=channels)
assert response.status_code == status.HTTP_200_OK
assert response.json()["processed"] == 2
# Verify groups created
groups = db_session.query(MockGroup).all()
assert len(groups) == 2
assert {g.name for g in groups} == {"Group A", "Group B"}
# Verify channels and URLs
channel1 = db_session.query(MockChannelDB).filter_by(name="Channel 1").first()
assert channel1 is not None
assert len(channel1.urls) == 2
assert channel1.urls[0].url == "http://stream1.com"
assert channel1.urls[0].priority_id == 100
assert channel1.urls[1].url == "http://backup1.com"
assert channel1.urls[1].priority_id == 200
channel2 = db_session.query(MockChannelDB).filter_by(name="Channel 2").first()
assert channel2 is not None
assert len(channel2.urls) == 1
assert channel2.urls[0].url == "http://stream2.com"
assert channel2.urls[0].priority_id == 100
def test_bulk_upload_empty(db_session, admin_user_client):
"""Test bulk upload with empty list"""
response = admin_user_client.post("/channels/bulk-upload", json=[])
assert response.status_code == status.HTTP_200_OK
assert response.json()["processed"] == 0
def test_bulk_upload_forbidden_for_non_admin(db_session, non_admin_user_client):
"""Test bulk upload requires admin role"""
response = non_admin_user_client.post("/channels/bulk-upload", json=[{}])
assert response.status_code == status.HTTP_403_FORBIDDEN
def test_bulk_upload_skip_missing_group_name(db_session, admin_user_client):
"""Test bulk upload skips channels with missing group name"""
channel_data = [{"name": "No Group Channel", "urls": ["http://no-group.com"]}]
response = admin_user_client.post("/channels/bulk-upload", json=channel_data)
assert response.status_code == status.HTTP_200_OK
assert response.json()["processed"] == 0
assert db_session.query(MockChannelDB).count() == 0
def test_bulk_upload_single_url_conversion(db_session, admin_user_client):
"""Test bulk upload converts single URL string to list"""
# Create priorities
priorities = [(100, "High"), (200, "Medium"), (300, "Low")]
for id, desc in priorities:
db_session.add(MockPriority(id=id, description=desc))
db_session.commit()
channel_data = [
{
"name": "Single URL Channel",
"group-title": "Test Group",
"urls": ["http://single-url.com"],
}
]
response = admin_user_client.post("/channels/bulk-upload", json=channel_data)
assert response.status_code == status.HTTP_200_OK
assert response.json()["processed"] == 1
channel = db_session.query(MockChannelDB).first()
assert channel is not None
urls = db_session.query(MockChannelURL).filter_by(channel_id=channel.id).all()
assert len(urls) == 1
assert urls[0].url == "http://single-url.com"
def test_bulk_upload_update_existing_channel(db_session, admin_user_client):
"""Test bulk upload updates existing channel and recreates URLs"""
# First create a group and channel
group_id = create_mock_priorities_and_group(
db_session, [(100, "High")], "Existing Group"
)
channel = MockChannelDB(
name="Existing Channel",
group_id=group_id,
tvg_id="existing.tv",
tvg_name="Existing",
tvg_logo="existing.png",
)
db_session.add(channel)
db_session.commit()
db_session.refresh(channel)
# Add some URLs
db_url1 = MockChannelURL(
channel_id=channel.id, url="http://old1.com", priority_id=100, in_use=False
)
db_url2 = MockChannelURL(
channel_id=channel.id, url="http://old2.com", priority_id=200, in_use=False
)
db_session.add_all([db_url1, db_url2])
db_session.commit()
# Bulk upload with same group and channel name but different URLs
channel_data = [
{
"name": "Existing Channel",
"group-title": "Existing Group",
"tvg-id": "updated.tv",
"tvg-name": "Updated",
"tvg-logo": "updated.png",
"urls": ["http://new1.com", "http://new2.com"],
}
]
response = admin_user_client.post("/channels/bulk-upload", json=channel_data)
assert response.status_code == status.HTTP_200_OK
assert response.json()["processed"] == 1
# Verify channel was updated
print(
"Channel after update:",
db_session.query(MockChannelDB).filter().first().id,
channel.tvg_id,
)
updated_channel = db_session.query(MockChannelDB).filter_by(id=channel.id).first()
assert updated_channel.tvg_id == "updated.tv"
assert updated_channel.tvg_name == "Updated"
assert updated_channel.tvg_logo == "updated.png"
# Verify old URLs were deleted and new ones created
urls = db_session.query(MockChannelURL).filter_by(channel_id=channel.id).all()
assert len(urls) == 2
assert {url.url for url in urls} == {"http://new1.com", "http://new2.com"}
def test_bulk_upload_error_handling(db_session, admin_user_client):
"""Test error handling in bulk upload continues processing"""
# Create a group first
create_mock_priorities_and_group(db_session, [(100, "High")], "Error Group")
channel_data = [
{
"name": "Good Channel",
"group-title": "Error Group",
"urls": ["http://good.com"],
},
{
"name": "Bad Channel",
"group-title": "Error Group",
"urls": None, # This will cause an error
},
{
"name": "Another Good Channel",
"group-title": "Error Group",
"urls": ["http://another-good.com"],
},
]
response = admin_user_client.post("/channels/bulk-upload", json=channel_data)
assert response.status_code == status.HTTP_200_OK
assert response.json()["processed"] == 2 # Only 2 successful
# Verify the good channels were processed
channels = db_session.query(MockChannelDB).all()
assert len(channels) == 2
assert {c.name for c in channels} == {"Good Channel", "Another Good Channel"}
def test_bulk_upload_channels_no_priorities(
db_session: Session, admin_user_client: TestClient
):
"""Test bulk upload when no priorities are defined in the database.
The channel should be processed, but its URLs should be skipped.
"""
# Ensure no priorities exist in the database
db_session.query(MockPriority).delete()
db_session.commit()
# Create a group for the channel
group = MockGroup(name="No Priority Group")
db_session.add(group)
db_session.commit()
db_session.refresh(group)
channel_data = [
{
"name": "Channel With No Priority URL",
"group-title": "No Priority Group",
"tvg-id": "nopriority.tv",
"tvg-name": "NoPriorityChannel",
"tvg-logo": "nopriority.png",
"urls": ["http://nopriority.com/stream"],
}
]
# Call the bulk upload endpoint
response = admin_user_client.post("/channels/bulk-upload", json=channel_data)
# Assert the response indicates 1 processed channel
assert response.status_code == status.HTTP_200_OK
assert response.json()["processed"] == 1
# Verify the channel was added to the database
db_channel = (
db_session.query(MockChannelDB)
.filter_by(name="Channel With No Priority URL")
.first()
)
assert db_channel is not None
assert db_channel.group_id == group.id
# Verify no URLs were added for this channel
assert (
db_session.query(MockChannelURL).filter_by(channel_id=db_channel.id).count()
== 0
)