"""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 = '''
This is content about test keyword services.
''' tier2_html = '''Check out our expert guide for more.
''' article1 = GeneratedContent( project_id=project.id, tier="tier1", keyword="test keyword 1", title="Test Article 1 - Tier 1", outline={"sections": []}, content="Test content
", 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="Test content 2
", 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="Test content 3
", 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="Test content 4
", 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()