Big-Link-Man/tests/integration/test_get_links_command.py

299 lines
9.7 KiB
Python

"""Integration tests for get-links CLI command"""
import pytest
from click.testing import CliRunner
from src.cli.commands import app
from src.database.models import Project, GeneratedContent, ArticleLink
from src.database.session import db_manager
@pytest.fixture
def cli_runner():
"""Create Click CLI runner"""
return CliRunner()
@pytest.fixture
def test_project_with_deployed_content():
"""Create a test project with deployed articles and tiered links"""
session = db_manager.get_session()
try:
project = Project(
name="Test Link Export Project",
main_keyword="test keyword",
user_id=1,
money_site_url="https://www.moneysite.com"
)
session.add(project)
session.flush()
tier1_html = '''
<html><body>
<h1>Test Article</h1>
<p>This is content about <a href="https://www.moneysite.com">test keyword</a> services.</p>
</body></html>
'''
tier2_html = '''
<html><body>
<h1>Test Tier 2</h1>
<p>Check out our <a href="https://cdn1.example.com/article1.html">expert guide</a> for more.</p>
</body></html>
'''
article1 = GeneratedContent(
project_id=project.id,
tier="tier1",
keyword="test keyword 1",
title="Test Article 1 - Tier 1",
outline={"sections": []},
content="<p>Test content</p>",
word_count=500,
status="deployed",
formatted_html=tier1_html,
deployed_url="https://cdn1.example.com/article1.html"
)
session.add(article1)
article2 = GeneratedContent(
project_id=project.id,
tier="tier1",
keyword="test keyword 2",
title="Test Article 2 - Tier 1",
outline={"sections": []},
content="<p>Test content 2</p>",
word_count=600,
status="deployed",
formatted_html=tier1_html,
deployed_url="https://cdn1.example.com/article2.html"
)
session.add(article2)
article3 = GeneratedContent(
project_id=project.id,
tier="tier2",
keyword="test keyword 3",
title="Test Article 3 - Tier 2",
outline={"sections": []},
content="<p>Test content 3</p>",
word_count=700,
status="deployed",
formatted_html=tier2_html,
deployed_url="https://cdn2.example.com/article3.html"
)
session.add(article3)
article4 = GeneratedContent(
project_id=project.id,
tier="tier3",
keyword="test keyword 4",
title="Test Article 4 - Tier 3",
outline={"sections": []},
content="<p>Test content 4</p>",
word_count=800,
status="deployed",
formatted_html=tier2_html,
deployed_url="https://cdn3.example.com/article4.html"
)
session.add(article4)
session.flush()
link1 = ArticleLink(
from_content_id=article1.id,
to_url="https://www.moneysite.com",
anchor_text="test keyword",
link_type="tiered"
)
session.add(link1)
link2 = ArticleLink(
from_content_id=article2.id,
to_url="https://www.moneysite.com",
anchor_text="test keyword",
link_type="tiered"
)
session.add(link2)
link3 = ArticleLink(
from_content_id=article3.id,
to_content_id=article1.id,
anchor_text="expert guide",
link_type="tiered"
)
session.add(link3)
link4 = ArticleLink(
from_content_id=article4.id,
to_content_id=article3.id,
anchor_text="expert guide",
link_type="tiered"
)
session.add(link4)
session.commit()
yield project, [article1, article2, article3, article4]
finally:
session.close()
class TestGetLinksCommand:
"""Test suite for get-links command"""
def test_get_links_basic_tier1(self, cli_runner, test_project_with_deployed_content):
"""Test basic tier 1 export without optional flags"""
project, articles = test_project_with_deployed_content
result = cli_runner.invoke(app, [
'get-links',
'--project-id', str(project.id),
'--tier', '1'
])
assert result.exit_code == 0
output = result.output
assert 'article_url,tier,title' in output
assert 'https://cdn1.example.com/article1.html' in output
assert 'https://cdn1.example.com/article2.html' in output
assert 'tier1' in output
assert 'https://cdn2.example.com/article3.html' not in output
def test_get_links_tier_range(self, cli_runner, test_project_with_deployed_content):
"""Test tier range filter (2+)"""
project, articles = test_project_with_deployed_content
result = cli_runner.invoke(app, [
'get-links',
'--project-id', str(project.id),
'--tier', '2+'
])
assert result.exit_code == 0
output = result.output
assert 'https://cdn2.example.com/article3.html' in output
assert 'https://cdn3.example.com/article4.html' in output
assert 'tier2' in output
assert 'tier3' in output
assert 'https://cdn1.example.com/article1.html' not in output
def test_get_links_with_anchor_text(self, cli_runner, test_project_with_deployed_content):
"""Test export with anchor text extraction"""
project, articles = test_project_with_deployed_content
result = cli_runner.invoke(app, [
'get-links',
'--project-id', str(project.id),
'--tier', '1',
'--with-anchor-text'
])
assert result.exit_code == 0
output = result.output
assert 'article_url,tier,title,anchor_text' in output
assert 'test keyword' in output
def test_get_links_with_destination_url(self, cli_runner, test_project_with_deployed_content):
"""Test export with destination URLs"""
project, articles = test_project_with_deployed_content
result = cli_runner.invoke(app, [
'get-links',
'--project-id', str(project.id),
'--tier', '1',
'--with-destination-url'
])
assert result.exit_code == 0
output = result.output
assert 'article_url,tier,title,destination_url' in output
assert 'https://www.moneysite.com' in output
def test_get_links_with_both_flags(self, cli_runner, test_project_with_deployed_content):
"""Test export with both anchor text and destination URL"""
project, articles = test_project_with_deployed_content
result = cli_runner.invoke(app, [
'get-links',
'--project-id', str(project.id),
'--tier', '1',
'--with-anchor-text',
'--with-destination-url'
])
assert result.exit_code == 0
output = result.output
assert 'article_url,tier,title,anchor_text,destination_url' in output
assert 'test keyword' in output
assert 'https://www.moneysite.com' in output
def test_get_links_tier2_resolves_content_id(self, cli_runner, test_project_with_deployed_content):
"""Test that tier 2 links resolve to_content_id to deployed URL"""
project, articles = test_project_with_deployed_content
result = cli_runner.invoke(app, [
'get-links',
'--project-id', str(project.id),
'--tier', '2',
'--with-destination-url'
])
assert result.exit_code == 0
output = result.output
assert 'https://cdn2.example.com/article3.html' in output
assert 'https://cdn1.example.com/article1.html' in output
def test_get_links_invalid_project(self, cli_runner):
"""Test error handling for non-existent project"""
result = cli_runner.invoke(app, [
'get-links',
'--project-id', '99999',
'--tier', '1'
])
assert result.exit_code == 1
assert 'Error: Project 99999 not found' in result.output
def test_get_links_invalid_tier_format(self, cli_runner, test_project_with_deployed_content):
"""Test error handling for invalid tier format"""
project, articles = test_project_with_deployed_content
result = cli_runner.invoke(app, [
'get-links',
'--project-id', str(project.id),
'--tier', 'invalid'
])
assert result.exit_code == 1
assert 'Invalid tier format' in result.output
def test_get_links_no_deployed_articles(self, cli_runner):
"""Test error handling when no deployed articles exist"""
session = db_manager.get_session()
try:
project = Project(
name="Empty Project",
main_keyword="empty",
user_id=1
)
session.add(project)
session.commit()
result = cli_runner.invoke(app, [
'get-links',
'--project-id', str(project.id),
'--tier', '1'
])
assert result.exit_code == 1
assert 'No deployed articles found' in result.output
finally:
session.close()