Fix dashboard stats aggregation

This commit is contained in:
Alexa Amundson
2025-11-16 04:34:27 -06:00
parent 902e21b760
commit b74340d639
3 changed files with 76 additions and 4 deletions

View File

@@ -4,6 +4,7 @@ from app.models.email import Email, EmailFolder
from app.models.social import Post, Comment, Like, Follow
from app.models.video import Video, VideoView, VideoLike
from app.models.file import File, Folder
from app.models.device import Device, DeviceMetric, DeviceLog
from app.models.blockchain import Block, Transaction, Wallet
from app.models.ai_chat import Conversation, Message
@@ -20,6 +21,9 @@ __all__ = [
"VideoLike",
"File",
"Folder",
"Device",
"DeviceMetric",
"DeviceLog",
"Block",
"Transaction",
"Wallet",

View File

@@ -10,7 +10,7 @@ Provides a comprehensive overview of all integrated services:
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, func
from sqlalchemy import select, func, cast, Integer
from typing import Dict, List, Any
from datetime import datetime, timedelta
import os
@@ -435,7 +435,7 @@ async def get_user_stats(db: AsyncSession, user: User) -> Dict[str, Any]:
# Social stats
posts_result = await db.execute(
select(func.count(Post.id)).filter(Post.author_id == user.id)
select(func.count(Post.id)).filter(Post.user_id == user.id)
)
posts_total = posts_result.scalar() or 0
@@ -449,7 +449,7 @@ async def get_user_stats(db: AsyncSession, user: User) -> Dict[str, Any]:
# Videos stats
videos_result = await db.execute(
select(func.count(Video.id), func.sum(Video.views)).filter(Video.uploader_id == user.id)
select(func.count(Video.id), func.sum(Video.views_count)).filter(Video.user_id == user.id)
)
videos_data = videos_result.first()
videos_total = videos_data[0] or 0
@@ -472,7 +472,7 @@ async def get_user_stats(db: AsyncSession, user: User) -> Dict[str, Any]:
# Devices stats
devices_result = await db.execute(
select(func.count(Device.id), func.sum(func.cast(Device.is_online, func.Integer)))
select(func.count(Device.id), func.sum(cast(Device.is_online, Integer)))
.filter(Device.owner_id == user.id)
)
devices_data = devices_result.first()

View File

@@ -0,0 +1,68 @@
"""Tests for dashboard overview statistics"""
import pytest
from httpx import AsyncClient
from sqlalchemy.ext.asyncio import AsyncSession
from app.models.social import Post
from app.models.video import Video
from app.models.device import Device
@pytest.mark.asyncio
async def test_dashboard_overview_reflects_user_content(
client: AsyncClient,
auth_headers,
db_session: AsyncSession,
test_user,
):
"""Ensure the dashboard aggregates posts, videos, and devices correctly."""
user_id = test_user["id"]
posts = [
Post(user_id=user_id, content="Post A"),
Post(user_id=user_id, content="Post B"),
]
videos = [
Video(user_id=user_id, title="Video 1", video_url="http://example.com/1", views_count=10),
Video(user_id=user_id, title="Video 2", video_url="http://example.com/2", views_count=25),
]
devices = [
Device(
device_id="dev-1",
name="Living Room Pi",
device_type="pi4",
owner_id=user_id,
is_online=True,
),
Device(
device_id="dev-2",
name="Bedroom Pi",
device_type="pi4",
owner_id=user_id,
is_online=False,
),
]
db_session.add_all(posts + videos + devices)
await db_session.commit()
response = await client.get("/api/dashboard/overview", headers=auth_headers)
assert response.status_code == 200
payload = response.json()
def get_service(name: str):
return next(service for service in payload["services"] if service["name"] == name)
social_stats = get_service("Social Media")["stats"]
assert social_stats["posts"] == len(posts)
video_stats = get_service("Video Platform")["stats"]
assert video_stats["videos"] == len(videos)
assert video_stats["views"] == sum(video.views_count for video in videos)
device_stats = get_service("Devices (IoT/Pi)")["stats"]
assert device_stats["total"] == len(devices)
assert device_stats["online"] == sum(1 for device in devices if device.is_online)