add views and db tests

This commit is contained in:
SwiftyOS
2024-11-08 13:31:10 +01:00
parent ef473bbc8d
commit 7f741468dd
4 changed files with 342 additions and 2 deletions

View File

@@ -104,7 +104,7 @@ async def get_store_agent_details(
return backend.server.v2.store.model.StoreAgentDetails(
slug=agent.slug,
agent_name=agent.agent_name,
agent_video=agent.agent_video,
agent_video=agent.agent_video or "",
agent_image=agent.agent_image,
creator=agent.creator_username,
creator_avatar=agent.creator_avatar,

View File

@@ -0,0 +1,226 @@
import pytest
from datetime import datetime
import backend.server.v2.store.db as db
import prisma.errors
import prisma.models
from backend.server.v2.store.model import CreatorDetails
from prisma import Prisma, register
@pytest.fixture(autouse=True)
async def setup_prisma():
try:
register(Prisma())
except:
pass
yield
@pytest.mark.asyncio
async def test_get_store_agents(mocker):
# Mock data
mock_agents = [
prisma.models.StoreAgent(
listing_id="test-id",
slug="test-agent",
agent_name="Test Agent",
agent_video=None,
agent_image=["image.jpg"],
featured=False,
creator_username="creator",
creator_avatar="avatar.jpg",
sub_heading="Test heading",
description="Test description",
categories=[],
runs=10,
rating=4.5,
versions=["1.0"],
)
]
# Mock prisma calls
mock_store_agent = mocker.patch("prisma.models.StoreAgent.prisma")
mock_store_agent.return_value.find_many = mocker.AsyncMock(return_value=mock_agents)
mock_store_agent.return_value.count = mocker.AsyncMock(return_value=1)
# Call function
result = await db.get_store_agents()
# Verify results
assert len(result.agents) == 1
assert result.agents[0].slug == "test-agent"
assert result.pagination.total_items == 1
# Verify mocks called correctly
mock_store_agent.return_value.find_many.assert_called_once()
mock_store_agent.return_value.count.assert_called_once()
@pytest.mark.asyncio
async def test_get_store_agent_details(mocker):
# Mock data
mock_agent = prisma.models.StoreAgent(
listing_id="test-id",
slug="test-agent",
agent_name="Test Agent",
agent_video="video.mp4",
agent_image=["image.jpg"],
featured=False,
creator_username="creator",
creator_avatar="avatar.jpg",
sub_heading="Test heading",
description="Test description",
categories=["test"],
runs=10,
rating=4.5,
versions=["1.0"],
)
# Mock prisma call
mock_store_agent = mocker.patch("prisma.models.StoreAgent.prisma")
mock_store_agent.return_value.find_first = mocker.AsyncMock(return_value=mock_agent)
# Call function
result = await db.get_store_agent_details("creator", "test-agent")
# Verify results
assert result.slug == "test-agent"
assert result.agent_name == "Test Agent"
# Verify mock called correctly
mock_store_agent.return_value.find_first.assert_called_once_with(
where={"creator_username": "creator", "slug": "test-agent"}
)
@pytest.mark.asyncio
async def test_get_store_creator_details(mocker):
# Mock data
mock_creator_data = prisma.models.Creator(
name="Test Creator",
username="creator",
description="Test description",
links=["link1"],
avatar_url="avatar.jpg",
num_agents=1,
agent_rating=4.5,
agent_runs=10,
top_categories=["test"],
)
# Mock prisma call
mock_creator = mocker.patch("prisma.models.Creator.prisma")
mock_creator.return_value.find_unique = mocker.AsyncMock()
# Configure the mock to return values that will pass validation
mock_creator.return_value.find_unique.return_value = mock_creator_data
# Call function
result = await db.get_store_creator_details("creator")
# Verify results
assert result.username == "creator"
assert result.name == "Test Creator"
assert result.description == "Test description"
assert result.avatar_url == "avatar.jpg"
# Verify mock called correctly
mock_creator.return_value.find_unique.assert_called_once_with(
where={"username": "creator"}
)
@pytest.mark.asyncio
async def test_create_store_submission(mocker):
# Mock data
mock_agent = prisma.models.AgentGraph(
id="agent-id",
version=1,
userId="user-id",
createdAt=datetime.now(),
isActive=True,
isTemplate=False,
)
mock_listing = prisma.models.StoreListing(
id="listing-id",
createdAt=datetime.now(),
updatedAt=datetime.now(),
isDeleted=False,
isApproved=False,
agentId="agent-id",
agentVersion=1,
owningUserId="user-id",
)
# Mock prisma calls
mock_agent_graph = mocker.patch("prisma.models.AgentGraph.prisma")
mock_agent_graph.return_value.find_first = mocker.AsyncMock(return_value=mock_agent)
mock_store_listing = mocker.patch("prisma.models.StoreListing.prisma")
mock_store_listing.return_value.find_first = mocker.AsyncMock(return_value=None)
mock_store_listing.return_value.create = mocker.AsyncMock(return_value=mock_listing)
# Call function
result = await db.create_store_submission(
user_id="user-id",
agent_id="agent-id",
agent_version=1,
slug="test-agent",
name="Test Agent",
description="Test description",
)
# Verify results
assert result.name == "Test Agent"
assert result.description == "Test description"
# Verify mocks called correctly
mock_agent_graph.return_value.find_first.assert_called_once()
mock_store_listing.return_value.find_first.assert_called_once()
mock_store_listing.return_value.create.assert_called_once()
@pytest.mark.asyncio
async def test_update_profile(mocker):
# Mock data
mock_profile = prisma.models.Profile(
id="profile-id",
name="Test Creator",
username="creator",
description="Test description",
links=["link1"],
avatarUrl="avatar.jpg",
createdAt=datetime.now(),
updatedAt=datetime.now(),
)
# Mock prisma calls
mock_profile_db = mocker.patch("prisma.models.Profile.prisma")
mock_profile_db.return_value.find_first = mocker.AsyncMock(
return_value=mock_profile
)
mock_profile_db.return_value.update = mocker.AsyncMock(return_value=mock_profile)
# Test data
profile = CreatorDetails(
name="Test Creator",
username="creator",
description="Test description",
links=["link1"],
avatar_url="avatar.jpg",
agent_rating=0.0,
agent_runs=0,
top_categories=[],
)
# Call function
result = await db.update_profile("user-id", profile)
# Verify results
assert result.username == "creator"
assert result.name == "Test Creator"
# Verify mocks called correctly
mock_profile_db.return_value.find_first.assert_called_once()
mock_profile_db.return_value.update.assert_called_once()

View File

@@ -0,0 +1,114 @@
BEGIN;
CREATE VIEW "StoreAgent" AS
WITH ReviewStats AS (
SELECT
sl."id" AS "storeListingId",
COUNT(sr.id) AS review_count,
AVG(CAST(sr.score AS DECIMAL)) AS avg_rating
FROM "StoreListing" sl
JOIN "StoreListingVersion" slv ON slv."storeListingId" = sl."id"
JOIN "StoreListingReview" sr ON sr."storeListingVersionId" = slv.id
WHERE sl."isDeleted" = FALSE
GROUP BY sl."id"
),
AgentRuns AS (
SELECT "agentGraphId", COUNT(*) AS run_count
FROM "AgentGraphExecution"
GROUP BY "agentGraphId"
)
SELECT
sl.id AS listing_id,
slv.slug,
a.name AS agent_name,
slv."videoUrl" AS agent_video,
COALESCE(slv."imageUrls", ARRAY[]::TEXT[]) AS agent_image,
slv."isFeatured" AS featured,
p.username AS creator_username,
p."avatarUrl" AS creator_avatar,
slv."subHeading" AS sub_heading,
slv.description,
slv.categories,
COALESCE(ar.run_count, 0) AS runs,
CAST(COALESCE(rs.avg_rating, 0.0) AS DOUBLE PRECISION) AS rating,
ARRAY_AGG(DISTINCT CAST(slv.version AS TEXT)) AS versions
FROM "StoreListing" sl
JOIN "AgentGraph" a ON sl."agentId" = a.id AND sl."agentVersion" = a."version"
LEFT JOIN "Profile" p ON sl."owningUserId" = p."userId"
LEFT JOIN "StoreListingVersion" slv ON slv."storeListingId" = sl.id
LEFT JOIN ReviewStats rs ON sl.id = rs."storeListingId"
LEFT JOIN AgentRuns ar ON a.id = ar."agentGraphId"
WHERE sl."isDeleted" = FALSE
AND sl."isApproved" = TRUE
GROUP BY sl.id, slv.slug, a.name, slv."videoUrl", slv."imageUrls", slv."isFeatured",
p.username, p."avatarUrl", slv."subHeading", slv.description, slv.categories,
ar.run_count, rs.avg_rating;
CREATE VIEW "Creator" AS
WITH AgentStats AS (
SELECT
p.username,
COUNT(DISTINCT sl.id) as num_agents,
AVG(CAST(COALESCE(sr.score, 0) AS DECIMAL)) as agent_rating,
SUM(COALESCE(age.run_count, 0)) as agent_runs
FROM "Profile" p
LEFT JOIN "StoreListing" sl ON sl."owningUserId" = p."userId"
LEFT JOIN "StoreListingVersion" slv ON slv."storeListingId" = sl.id
LEFT JOIN "StoreListingReview" sr ON sr."storeListingVersionId" = slv.id
LEFT JOIN (
SELECT "agentGraphId", COUNT(*) as run_count
FROM "AgentGraphExecution"
GROUP BY "agentGraphId"
) age ON age."agentGraphId" = sl."agentId"
WHERE sl."isDeleted" = FALSE AND sl."isApproved" = TRUE
GROUP BY p.username
)
SELECT
p.username,
p.name,
p."avatarUrl" as avatar_url,
p.description,
ARRAY_AGG(DISTINCT c) FILTER (WHERE c IS NOT NULL) as top_categories,
p.links,
COALESCE(ast.num_agents, 0) as num_agents,
COALESCE(ast.agent_rating, 0.0) as agent_rating,
COALESCE(ast.agent_runs, 0) as agent_runs
FROM "Profile" p
LEFT JOIN AgentStats ast ON ast.username = p.username
LEFT JOIN LATERAL (
SELECT UNNEST(slv.categories) as c
FROM "StoreListing" sl
JOIN "StoreListingVersion" slv ON slv."storeListingId" = sl.id
WHERE sl."owningUserId" = p."userId"
AND sl."isDeleted" = FALSE
AND sl."isApproved" = TRUE
) cats ON true
GROUP BY p.username, p.name, p."avatarUrl", p.description, p.links,
ast.num_agents, ast.agent_rating, ast.agent_runs;
CREATE VIEW "StoreSubmission" AS
SELECT
sl.id as listing_id,
sl."owningUserId" as user_id,
slv.name,
slv.description,
slv."imageUrls" as image_urls,
sls."createdAt" as date_submitted,
sls."Status" as status,
COALESCE(ar.run_count, 0) as runs,
CAST(COALESCE(AVG(CAST(sr.score AS DECIMAL)), 0.0) AS DOUBLE PRECISION) as rating
FROM "StoreListing" sl
JOIN "StoreListingVersion" slv ON slv."storeListingId" = sl.id
LEFT JOIN "StoreListingSubmission" sls ON sls."storeListingId" = sl.id
LEFT JOIN "StoreListingReview" sr ON sr."storeListingVersionId" = slv.id
LEFT JOIN (
SELECT "agentGraphId", COUNT(*) as run_count
FROM "AgentGraphExecution"
GROUP BY "agentGraphId"
) ar ON ar."agentGraphId" = sl."agentId"
WHERE sl."isDeleted" = FALSE
GROUP BY sl.id, sl."owningUserId", slv.name, slv.description, slv."imageUrls",
sls."createdAt", sls."Status", ar.run_count;
COMMIT;

View File

@@ -431,7 +431,7 @@ view StoreAgent {
slug String
agent_name String
agent_video String
agent_video String?
agent_image String[]
featured Boolean @default(false)