""" Test for Issue Wrap-up Bug Fix This test reproduces and validates the fix for the bug where IssueWrapUpService._review_requirements() incorrectly calls .get() on IssueActivity dataclass objects instead of using attribute access. Bug: 'IssueActivity' object has no attribute 'get' Location: markitect/issues/issue_wrapup_commands.py lines 135-136 """ import pytest import tempfile from pathlib import Path from datetime import date from markitect.issues.issue_wrapup_commands import IssueWrapUpService from markitect.issues.activity_tracker import IssueActivityTracker, ActivityType from markitect.finance.models import FinanceModels class TestIssueWrapUpBugFix: """Test suite for issue wrap-up bug fix.""" @pytest.fixture def temp_db(self): """Create temporary database for testing.""" with tempfile.NamedTemporaryFile(suffix='.db', delete=False) as f: db_path = f.name # Initialize schema finance_models = FinanceModels(db_path) finance_models.initialize_finance_schema() yield db_path # Cleanup Path(db_path).unlink(missing_ok=True) @pytest.fixture def issue_wrapup_service(self, temp_db): """Create IssueWrapUpService instance for testing.""" return IssueWrapUpService(temp_db) @pytest.fixture def sample_issue_activities(self, temp_db): """Create sample issue activities that trigger the bug.""" activity_tracker = IssueActivityTracker(temp_db) # Create activities that will be processed by _review_requirements activity_ids = [] # Activity with implementation-related content activity_ids.append(activity_tracker.log_activity( issue_id=114, activity_type=ActivityType.CREATED, activity_date=date(2025, 10, 5), activity_details="Implementing cost allocation engine" )) # Activity with code-related content activity_ids.append(activity_tracker.log_activity( issue_id=114, activity_type=ActivityType.MODIFIED, activity_date=date(2025, 10, 6), activity_details="Added code for transaction handling" )) return activity_ids def test_reproduce_issueactivity_get_attribute_error(self, issue_wrapup_service, sample_issue_activities): """ Test that reproduces the 'IssueActivity' object has no attribute 'get' error. This test should fail with the original buggy code and pass after the fix. """ # This should trigger the bug in the original code where it calls: # activity.get('activity_type', '') and activity.get('description', '') # on IssueActivity dataclass objects instead of using proper attribute access try: # Call the method that contains the bug result = issue_wrapup_service._review_requirements( issue_number=114, issue_details={'number': 114, 'title': 'Test Issue'}, force=False ) # If we get here without an AttributeError, the bug is fixed assert isinstance(result, dict) assert 'success' in result assert 'activities_count' in result assert 'has_implementation_activity' in result # The logic should find implementation activities assert result['activities_count'] == 2 assert result['has_implementation_activity'] is True # Should find 'implement' and 'code' assert result['success'] is True except AttributeError as e: if "'IssueActivity' object has no attribute 'get'" in str(e): pytest.fail(f"Bug reproduced: {e}") else: # Different AttributeError, re-raise raise def test_review_requirements_with_no_activities(self, issue_wrapup_service): """Test _review_requirements when no activities exist.""" result = issue_wrapup_service._review_requirements( issue_number=999, # Non-existent issue issue_details={'number': 999, 'title': 'Non-existent Issue'}, force=False ) assert result['success'] is False assert result['activities_count'] == 0 assert result['has_implementation_activity'] is False def test_review_requirements_with_force_flag(self, issue_wrapup_service): """Test _review_requirements with force flag bypasses checks.""" result = issue_wrapup_service._review_requirements( issue_number=999, # Non-existent issue issue_details={'number': 999, 'title': 'Non-existent Issue'}, force=True ) assert result['success'] is True assert result['forced'] is True def test_activity_content_detection(self, issue_wrapup_service, temp_db): """Test that the fixed code correctly detects implementation activities.""" # Create activities with different content types activity_tracker = IssueActivityTracker(temp_db) # Create activity with 'implement' in description activity_tracker.log_activity( issue_id=115, activity_type=ActivityType.CREATED, activity_details="Need to implement the feature" ) # Create activity with 'code' in description activity_tracker.log_activity( issue_id=115, activity_type=ActivityType.MODIFIED, activity_details="Updated code for better performance" ) # Create activity with neither keyword activity_tracker.log_activity( issue_id=115, activity_type=ActivityType.COMMENTED, activity_details="Just a regular comment" ) result = issue_wrapup_service._review_requirements( issue_number=115, issue_details={'number': 115, 'title': 'Test Issue'}, force=False ) assert result['activities_count'] == 3 assert result['has_implementation_activity'] is True # Should find 'implement' and 'code' assert result['success'] is True if __name__ == '__main__': pytest.main([__file__])