""" Tests for advanced routes: Family Tree, Timeline, Concordance, and Study Guides. These tests cover complex, user-facing features with multiple routes and data dependencies. """ import pytest class TestFamilyTreeRoutes: """Tests for biblical family tree genealogy routes""" def test_family_tree_main_page(self, client): """Test main family tree page loads""" response = client.get("/family-tree") assert response.status_code == 200 content = response.content.decode() assert "family" in content.lower() or "tree" in content.lower() def test_family_tree_has_generations(self, client): """Test family tree page displays generation information""" response = client.get("/family-tree") assert response.status_code == 200 content = response.content.decode() # Should reference generations or genealogy assert "generation" in content.lower() or "genealogy" in content.lower() def test_family_tree_generation_page(self, client): """Test individual generation page loads""" # Test generation 1 (Adam/Eve) response = client.get("/family-tree/generation/1") assert response.status_code == 200 content = response.content.decode() assert "generation" in content.lower() def test_family_tree_generation_adam(self, client): """Test generation 1 contains Adam""" response = client.get("/family-tree/generation/1") assert response.status_code == 200 content = response.content.decode() assert "Adam" in content or "adam" in content.lower() def test_family_tree_invalid_generation(self, client): """Test non-existent generation returns 404""" response = client.get("/family-tree/generation/999") assert response.status_code == 404 def test_family_tree_person_page(self, client): """Test individual person page loads""" # Test Adam's page response = client.get("/family-tree/person/i1") assert response.status_code in [200, 404] # May or may not exist depending on GEDCOM data if response.status_code == 200: content = response.content.decode() # Should have person information assert len(content) > 100 def test_family_tree_person_not_found(self, client): """Test non-existent person returns 404""" response = client.get("/family-tree/person/invalid-person-id-xyz") assert response.status_code == 404 def test_family_tree_search_page(self, client): """Test family tree search page loads""" response = client.get("/family-tree/search") assert response.status_code == 200 content = response.content.decode() assert "search" in content.lower() def test_family_tree_search_with_query(self, client): """Test family tree search with query parameter""" response = client.get("/family-tree/search?q=Adam") assert response.status_code in [200, 303] # 303 if exact match redirects if response.status_code == 200: content = response.content.decode() assert "Adam" in content or "adam" in content.lower() def test_family_tree_search_empty_query(self, client): """Test family tree search with empty query""" response = client.get("/family-tree/search?q=") assert response.status_code == 200 def test_family_tree_lineage_page(self, client): """Test Messianic lineage page loads""" response = client.get("/family-tree/lineage") assert response.status_code == 200 content = response.content.decode() assert "lineage" in content.lower() or "messiah" in content.lower() def test_family_tree_lineage_svg(self, client): """Test Messianic lineage SVG generation""" response = client.get("/family-tree/lineage.svg") assert response.status_code == 200 assert response.headers["content-type"] == "image/svg+xml" # Verify it's valid SVG content = response.content.decode() assert "" in content def test_family_tree_descendants_page(self, client): """Test descendants view for a person""" # Test Adam's descendants response = client.get("/family-tree/person/i1/descendants") assert response.status_code in [200, 404] # 404 if person not found if response.status_code == 200: content = response.content.decode() assert "descendants" in content.lower() or "descendant" in content.lower() def test_family_tree_descendants_invalid_person(self, client): """Test descendants view for non-existent person""" response = client.get("/family-tree/person/invalid-xyz/descendants") assert response.status_code == 404 def test_family_tree_ancestors_page(self, client): """Test ancestors view for a person""" # Test Jesus's ancestors response = client.get("/family-tree/person/i42/ancestors") assert response.status_code in [200, 404] # 404 if person not found if response.status_code == 200: content = response.content.decode() assert "ancestors" in content.lower() or "ancestor" in content.lower() def test_family_tree_ancestors_invalid_person(self, client): """Test ancestors view for non-existent person""" response = client.get("/family-tree/person/invalid-xyz/ancestors") assert response.status_code == 404 def test_family_tree_navigation_links(self, client): """Test family tree pages have proper navigation""" response = client.get("/family-tree") assert response.status_code == 200 content = response.content.decode() # Should have links to persons or generations assert "/family-tree/" in content class TestBiblicalTimelineRoutes: """Tests for biblical timeline routes""" def test_timeline_page_loads(self, client): """Test biblical timeline page loads""" response = client.get("/biblical-timeline") assert response.status_code == 200 content = response.content.decode() assert "timeline" in content.lower() def test_timeline_has_events(self, client): """Test timeline displays biblical events""" response = client.get("/biblical-timeline") assert response.status_code == 200 content = response.content.decode() # Should contain references to major biblical events or periods assert ( "creation" in content.lower() or "flood" in content.lower() or "abraham" in content.lower() or "exodus" in content.lower() or "christ" in content.lower() ) def test_timeline_has_dates(self, client): """Test timeline includes chronological dates""" response = client.get("/biblical-timeline") assert response.status_code == 200 content = response.content.decode() # Should have BC dates assert "BC" in content or "BCE" in content or "AM" in content def test_timeline_pdf_generation(self, client): """Test timeline PDF generation""" response = client.get("/biblical-timeline/pdf") # PDF generation might not be available assert response.status_code in [200, 500, 503] if response.status_code == 200: assert response.headers["content-type"] == "application/pdf" # Verify it's a PDF assert response.content[:4] == b'%PDF' def test_timeline_metadata(self, client): """Test timeline page has proper metadata""" response = client.get("/biblical-timeline") assert response.status_code == 200 content = response.content.decode() # Should have HTML structure assert "" in content class TestStrongsRoutes: """Tests for Strong's Concordance routes""" def test_strongs_page_loads(self, client): """Test Strong's index page loads""" response = client.get("/strongs") assert response.status_code == 200 content = response.content.decode() assert "strong" in content.lower() def test_strongs_has_search(self, client): """Test Strong's page has search functionality""" response = client.get("/strongs") assert response.status_code == 200 content = response.content.decode() # Should have search input or form assert "search" in content.lower() def test_strongs_with_search_query(self, client): """Test Strong's with search query""" response = client.get("/strongs?q=love") assert response.status_code == 200 content = response.content.decode() # Should display results for "love" assert "love" in content.lower() def test_strongs_entry_page(self, client): """Test Strong's entry page loads""" response = client.get("/strongs/G26") assert response.status_code == 200 content = response.content.decode() # Should have agape (love) assert "agape" in content.lower() or "ἀγάπη" in content def test_strongs_hebrew_entry(self, client): """Test Hebrew Strong's entry page""" response = client.get("/strongs/H430") assert response.status_code == 200 content = response.content.decode() # Should have Elohim (God) assert "elohim" in content.lower() or "אֱלֹהִים" in content def test_strongs_hebrew_index(self, client): """Test Hebrew Strong's index page""" response = client.get("/strongs/hebrew") assert response.status_code == 200 content = response.content.decode() # Should have Hebrew entries assert "Hebrew" in content assert "H1" in content or "H2" in content def test_strongs_greek_index(self, client): """Test Greek Strong's index page""" response = client.get("/strongs/greek") assert response.status_code == 200 content = response.content.decode() # Should have Greek entries assert "Greek" in content assert "G1" in content or "G2" in content def test_strongs_pagination(self, client): """Test Strong's index pagination""" response = client.get("/strongs/hebrew?page=2") assert response.status_code == 200 content = response.content.decode() # Should show page 2 assert "Page 2" in content or "page=1" in content def test_strongs_invalid_entry(self, client): """Test invalid Strong's number returns 404""" response = client.get("/strongs/X9999") assert response.status_code == 404 class TestStudyGuidesRoutes: """Tests for study guides routes""" def test_study_guides_index_loads(self, client): """Test study guides index page loads""" response = client.get("/study-guides") assert response.status_code == 200 content = response.content.decode() assert "study" in content.lower() or "guide" in content.lower() def test_study_guides_has_categories(self, client): """Test study guides index has categories""" response = client.get("/study-guides") assert response.status_code == 200 content = response.content.decode() # Should have study guide categories or links assert len(content) > 1000 # Substantial content def test_study_guides_has_links(self, client): """Test study guides index links to individual guides""" response = client.get("/study-guides") assert response.status_code == 200 content = response.content.decode() # Should have links to individual study guides assert "/study-guides/" in content def test_study_guide_detail_page(self, client): """Test individual study guide detail page""" # Test a common study guide slug response = client.get("/study-guides/salvation") assert response.status_code in [200, 404] if response.status_code == 200: content = response.content.decode() assert "salvation" in content.lower() def test_study_guide_gospel(self, client): """Test gospel study guide""" response = client.get("/study-guides/gospel") assert response.status_code in [200, 404] if response.status_code == 200: content = response.content.decode() assert "gospel" in content.lower() def test_study_guide_prayer_faith(self, client): """Test prayer & faith study guide""" response = client.get("/study-guides/prayer-faith") assert response.status_code in [200, 404] def test_study_guide_invalid_slug(self, client): """Test non-existent study guide returns 404""" response = client.get("/study-guides/this-guide-does-not-exist") assert response.status_code == 404 def test_study_guide_has_verses(self, client): """Test study guide pages include verse references""" response = client.get("/study-guides/salvation") if response.status_code == 200: content = response.content.decode() # Should have verse references or Bible links assert ( "/book/" in content or "verse" in content.lower() or "chapter" in content.lower() ) def test_study_guide_pdf_generation(self, client): """Test study guide PDF generation""" response = client.get("/study-guides/salvation/pdf") # PDF might not be available or guide might not exist assert response.status_code in [200, 404, 500, 503] if response.status_code == 200: assert response.headers["content-type"] == "application/pdf" # Verify it's a PDF assert response.content[:4] == b'%PDF' def test_study_guide_pdf_invalid_slug(self, client): """Test PDF for non-existent study guide returns error""" response = client.get("/study-guides/invalid-guide-xyz/pdf") # Should return 404 for invalid guide, or 503 if WeasyPrint not available assert response.status_code in [404, 503] def test_study_guide_navigation(self, client): """Test study guide pages have breadcrumbs/navigation""" response = client.get("/study-guides/salvation") if response.status_code == 200: content = response.content.decode() # Should have navigation back to study guides assert "/study-guides" in content or "study guide" in content.lower() class TestAdvancedRoutesIntegration: """Integration tests across multiple advanced route types""" def test_all_major_pages_load(self, client): """Test all major advanced pages load successfully""" pages = [ "/family-tree", "/biblical-timeline", "/strongs", "/study-guides", ] for page in pages: response = client.get(page) assert response.status_code == 200, f"Page {page} failed to load" def test_pages_have_html_structure(self, client): """Test pages have valid HTML structure""" pages = [ "/family-tree", "/biblical-timeline", "/strongs", "/study-guides", ] for page in pages: response = client.get(page) if response.status_code == 200: content = response.content.decode() assert "" in content.lower() def test_pages_have_titles(self, client): """Test pages have proper title tags""" pages = [ "/family-tree", "/biblical-timeline", "/strongs", "/study-guides", ] for page in pages: response = client.get(page) if response.status_code == 200: content = response.content.decode() assert "" in content.lower() def test_pages_return_html_content_type(self, client): """Test HTML pages return correct content type""" pages = [ "/family-tree", "/biblical-timeline", "/strongs", "/study-guides", ] for page in pages: response = client.get(page) if response.status_code == 200: content_type = response.headers.get("content-type", "") assert "text/html" in content_type if __name__ == "__main__": pytest.main([__file__, "-v"])