299 lines
9.7 KiB
Python
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()
|
|
|