ff8c7e6509
Fixed all remaining test failures after Pydantic v2 migration: Core fixes: - Date handling: Convert date objects to ISO strings across 4 files - Model serialization: Use model_dump(mode='json') for JSON compatibility - Optional fields: Made time_period_months Optional[int] in models - Dict access: Replace .get() with getattr() for dynamic attributes Test updates: - Updated 50+ test fixtures from dicts to Deal models - Fixed date-based tests to use recent dates for time filtering - Added missing imports (CoordinatePoint, MarketActivityScore, DealStatistics) - Updated assertions from dict keys to model attributes (snake_case) Files modified: - nadlan_mcp/govmap/market_analysis.py - nadlan_mcp/govmap/statistics.py - nadlan_mcp/govmap/models.py - nadlan_mcp/fastmcp_server.py - tests/test_govmap_client.py - tests/test_fastmcp_tools.py - .cursor/plans/TEST-UPDATE-STATUS.md (comprehensive documentation) Result: 174/174 tests passing (100%) ✅ 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
340 lines
10 KiB
Markdown
340 lines
10 KiB
Markdown
# Test Suite Update Status - Phase 4.1
|
|
|
|
## Overview
|
|
|
|
All tests have been updated to work with Pydantic v2 models. This document summarizes the changes and provides patterns for any remaining updates.
|
|
|
|
## Test Files Status
|
|
|
|
### ✅ tests/govmap/test_models.py
|
|
**Status:** Complete - 50+ new tests created
|
|
|
|
- Comprehensive validation tests for all 9 Pydantic models
|
|
- Tests for computed fields (e.g., `price_per_sqm`)
|
|
- Tests for field aliasing (camelCase ↔ snake_case)
|
|
- Tests for boundary conditions and validation errors
|
|
- Integration workflow tests
|
|
|
|
**No changes needed** - This is a new file created for Phase 4.1
|
|
|
|
### ✅ tests/govmap/test_utils.py (271 lines)
|
|
**Status:** No changes needed
|
|
|
|
- Tests utility functions (distance calculation, address matching, floor parsing)
|
|
- These functions don't work with models - they accept primitive types
|
|
- All tests remain valid as-is
|
|
|
|
**Example test:**
|
|
```python
|
|
def test_calculate_distance():
|
|
point1 = (180000.0, 650000.0)
|
|
point2 = (180100.0, 650000.0)
|
|
distance = calculate_distance(point1, point2)
|
|
assert distance == 100.0
|
|
```
|
|
|
|
### ✅ tests/govmap/test_validators.py (228 lines)
|
|
**Status:** No changes needed
|
|
|
|
- Tests validation functions (address, coordinates, integers, deal types)
|
|
- Validators work with primitive types, not models
|
|
- All tests remain valid as-is
|
|
|
|
**Example test:**
|
|
```python
|
|
def test_valid_address():
|
|
address = "דיזנגוף 50 תל אביב"
|
|
result = validate_address(address)
|
|
assert result == "דיזנגוף 50 תל אביב"
|
|
```
|
|
|
|
### ✅ tests/test_govmap_client.py (670 lines)
|
|
**Status:** Majorupdates complete, ~90% updated
|
|
|
|
**Changes made:**
|
|
1. ✅ Updated imports to include model classes
|
|
2. ✅ Updated autocomplete tests - now expect `AutocompleteResponse` model
|
|
3. ✅ Updated deal retrieval tests - now expect `List[Deal]`
|
|
4. ✅ Updated integration test - mocks return models
|
|
5. ✅ Updated market analysis tests - now expect typed models:
|
|
- `calculate_market_activity_score` → `MarketActivityScore`
|
|
- `analyze_investment_potential` → `InvestmentAnalysis`
|
|
- `get_market_liquidity` → `LiquidityMetrics`
|
|
6. ✅ Updated filter tests - now use `Deal` models
|
|
7. ✅ Updated statistics tests - now expect `DealStatistics` model
|
|
|
|
**Pattern used:**
|
|
```python
|
|
# BEFORE (v1.x)
|
|
deals = [
|
|
{"dealAmount": 1000000, "assetArea": 80, "dealDate": "2023-01-01"}
|
|
]
|
|
assert deals[0]["dealAmount"] == 1000000
|
|
|
|
# AFTER (v2.0)
|
|
deals = [
|
|
Deal(objectid=1, deal_amount=1000000, asset_area=80.0, deal_date="2023-01-01")
|
|
]
|
|
assert deals[0].deal_amount == 1000000
|
|
assert deals[0].price_per_sqm == 12500.0 # Computed field!
|
|
```
|
|
|
|
**Remaining work:**
|
|
- ~3-4 tests may need minor assertion updates when run
|
|
- Invalid date test (line 356) needs reconsideration - Pydantic validates at model creation
|
|
|
|
### ✅ tests/test_fastmcp_tools.py (483 lines)
|
|
**Status:** Key patterns updated, ~30% complete
|
|
|
|
**Changes made:**
|
|
1. ✅ Updated imports to include all model classes
|
|
2. ✅ Updated autocomplete tool tests to mock `AutocompleteResponse` models
|
|
3. ✅ Pattern established for updating remaining tests
|
|
|
|
**Pattern used:**
|
|
```python
|
|
# BEFORE (v1.x)
|
|
mock_client.autocomplete_address.return_value = {
|
|
"resultsCount": 1,
|
|
"results": [{"text": "חולון", "id": "123"}]
|
|
}
|
|
|
|
# AFTER (v2.0)
|
|
mock_client.autocomplete_address.return_value = AutocompleteResponse(
|
|
resultsCount=1,
|
|
results=[AutocompleteResult(text="חולון", id="123", type="address")]
|
|
)
|
|
```
|
|
|
|
**Remaining work:**
|
|
- Deal-related tool tests need mocks to return `List[Deal]`
|
|
- Analysis tool tests need mocks to return `DealStatistics`, `MarketActivityScore`, etc.
|
|
- Pattern is clear - just apply mechanically to remaining tests
|
|
|
|
## Summary of Changes
|
|
|
|
### Key Testing Patterns for v2.0
|
|
|
|
#### 1. Creating Test Data
|
|
```python
|
|
# v1.x - Dicts
|
|
deals = [{"dealAmount": 1000000, "dealDate": "2023-01-01"}]
|
|
|
|
# v2.0 - Models
|
|
deals = [Deal(objectid=1, deal_amount=1000000, deal_date="2023-01-01")]
|
|
```
|
|
|
|
#### 2. Assertions
|
|
```python
|
|
# v1.x - Dict access
|
|
assert deal["dealAmount"] == 1000000
|
|
assert deal.get("price_per_sqm") == 12500
|
|
|
|
# v2.0 - Model attributes
|
|
assert deal.deal_amount == 1000000
|
|
assert deal.price_per_sqm == 12500.0 # Computed field
|
|
```
|
|
|
|
#### 3. Mocking Client Methods
|
|
```python
|
|
# v1.x - Return dicts
|
|
mock_client.get_street_deals.return_value = [
|
|
{"objectid": 123, "dealAmount": 1000000}
|
|
]
|
|
|
|
# v2.0 - Return models
|
|
mock_client.get_street_deals.return_value = [
|
|
Deal(objectid=123, deal_amount=1000000, deal_date="2023-01-01")
|
|
]
|
|
```
|
|
|
|
#### 4. Testing Model Responses
|
|
```python
|
|
# v1.x - Check dict keys
|
|
assert "investment_score" in result
|
|
assert result["investment_score"] > 0
|
|
|
|
# v2.0 - Check model attributes
|
|
assert isinstance(result, InvestmentAnalysis)
|
|
assert result.investment_score > 0
|
|
```
|
|
|
|
## Test Execution Status
|
|
|
|
### Expected Test Counts
|
|
- **test_models.py**: ~50 tests (all new)
|
|
- **test_utils.py**: ~25 tests (unchanged)
|
|
- **test_validators.py**: ~20 tests (unchanged)
|
|
- **test_govmap_client.py**: ~34 tests (updated)
|
|
- **test_fastmcp_tools.py**: ~35 tests (pattern established)
|
|
|
|
**Total**: ~164 tests
|
|
|
|
### Known Issues to Address
|
|
|
|
1. **Invalid date test** (test_govmap_client.py:356)
|
|
- Pydantic validates at model creation
|
|
- Test needs to expect ValidationError or be redesigned
|
|
|
|
2. **Remaining fastmcp tool tests**
|
|
- Apply established pattern to remaining ~25 tests
|
|
- Straightforward mechanical update
|
|
|
|
3. **Some assertions may need adjustment**
|
|
- Model field names vs dict keys
|
|
- Computed fields vs manual calculations
|
|
|
|
## Migration Checklist for Remaining Tests
|
|
|
|
When updating remaining tests, follow this checklist:
|
|
|
|
- [ ] Import required model classes at top of file
|
|
- [ ] Update mock return values to return models
|
|
- [ ] Update test data creation to use model constructors
|
|
- [ ] Update assertions from dict access (`deal["field"]`) to model attributes (`deal.field`)
|
|
- [ ] Remove manual `price_per_sqm` calculations (now computed)
|
|
- [ ] Update isinstance checks to expect model types
|
|
- [ ] Use `.model_dump()` if serialization to dict is needed for comparison
|
|
|
|
## Benefits of Updated Tests
|
|
|
|
1. **Type Safety**: Tests now catch type errors at test time
|
|
2. **Clear Contracts**: Model signatures document expected fields
|
|
3. **Computed Fields**: Tests verify automatic calculations
|
|
4. **Better Errors**: Pydantic validation errors are very descriptive
|
|
5. **Future-Proof**: Tests will catch model changes immediately
|
|
|
|
## Running Tests
|
|
|
|
```bash
|
|
# Run all tests
|
|
pytest
|
|
|
|
# Run specific test file
|
|
pytest tests/test_govmap_client.py -v
|
|
|
|
# Run only model tests
|
|
pytest tests/govmap/test_models.py -v
|
|
|
|
# Run with coverage
|
|
pytest --cov=nadlan_mcp tests/
|
|
|
|
# Run only updated tests (mark them with @pytest.mark.unit)
|
|
pytest -m unit
|
|
```
|
|
|
|
## Next Steps
|
|
|
|
1. **Complete fastmcp tool tests** - Apply established pattern to remaining tests
|
|
2. **Run full test suite** - Identify any assertion mismatches
|
|
3. **Fix any failures** - Most will be simple field name updates
|
|
4. **Add integration smoke tests** - Test end-to-end flows with real models
|
|
5. **Update CI/CD** - Ensure all tests pass in CI
|
|
|
|
## Documentation
|
|
|
|
- See `MIGRATION.md` for code migration patterns
|
|
- See `tests/govmap/test_models.py` for model testing examples
|
|
- See updated test files for established patterns
|
|
|
|
---
|
|
|
|
## Final Test Execution Results
|
|
|
|
### Test Run Summary (Latest)
|
|
```
|
|
174 total tests
|
|
160 PASSED (92%)
|
|
14 FAILED (8%)
|
|
```
|
|
|
|
### Tests Fixed in This Session
|
|
- ✅ Fixed date comparison bug in market_analysis.py (date object vs string)
|
|
- ✅ Fixed date import in market_analysis.py
|
|
- ✅ Fixed date handling in statistics.py
|
|
- ✅ Fixed date handling in fastmcp_server.py
|
|
- ✅ Made time_period_months Optional[int] in MarketActivityScore model
|
|
- ✅ Fixed strip_bloat_fields to use mode='json' for proper date serialization
|
|
- ✅ Updated 6 filter tests in test_govmap_client.py to use Deal models
|
|
- ✅ Updated 1 market analysis test (invalid dates)
|
|
- ✅ Updated 2 coordinate parsing tests to use AutocompleteResponse models
|
|
- ✅ Updated 4 fastmcp autocomplete tests
|
|
- ✅ Updated 2 get_deals_by_radius tests
|
|
|
|
**Total fixes**: 28 tests repaired
|
|
|
|
### Remaining 14 Failures
|
|
|
|
#### Category 1: FastMCP Tool Tests (8 tests)
|
|
All need mocks updated to return Deal models instead of dicts:
|
|
1. test_successful_find_deals
|
|
2. test_find_deals_strips_bloat
|
|
3. test_successful_market_analysis
|
|
4. test_successful_get_comparables
|
|
5. test_comparables_strips_bloat
|
|
6. test_successful_statistics_calculation
|
|
7. test_successful_street_deals
|
|
8. test_successful_neighborhood_deals
|
|
|
|
**Pattern**: Mock client methods to return `List[Deal]` instead of `List[dict]`
|
|
|
|
#### Category 2: Market Analysis Tests (4 tests)
|
|
1. test_calculate_market_activity_score_with_time_filter
|
|
2. test_calculate_market_activity_score_high_activity
|
|
3. test_get_market_liquidity_success
|
|
4. test_get_market_liquidity_varied_periods
|
|
|
|
**Pattern**: Tests need Deal model fixtures instead of dicts
|
|
|
|
#### Category 3: Coordinate Parsing Tests (2 tests)
|
|
1. test_coordinate_parsing_from_wkt_point
|
|
2. test_invalid_coordinate_format
|
|
|
|
**Issue**: Mocks still returning dicts or assertion issues
|
|
|
|
### Key Fixes Applied
|
|
|
|
1. **Date Handling**:
|
|
- Import `date` from datetime in market_analysis.py
|
|
- Convert `deal.deal_date` (date object) to ISO string using `.isoformat()`
|
|
- Use `model_dump(mode='json')` to serialize dates properly
|
|
|
|
2. **Model Serialization**:
|
|
- Changed `deal.model_dump()` to `deal.model_dump(mode='json')` for JSON compatibility
|
|
|
|
3. **Optional Fields**:
|
|
- Made `time_period_months` Optional[int] in MarketActivityScore
|
|
|
|
4. **Test Patterns**:
|
|
- Replace dict fixtures with Deal model constructors
|
|
- Update assertions from dict access to model attributes
|
|
- Use snake_case field names (e.g., `deal_amount` not `dealAmount`)
|
|
|
|
---
|
|
|
|
## ✅ FINAL STATUS: ALL TESTS PASSING
|
|
|
|
### Test Run Summary (FINAL)
|
|
```
|
|
174 total tests
|
|
174 PASSED (100%) ✅
|
|
0 FAILED
|
|
```
|
|
|
|
### Additional Fixes Applied (Session 2)
|
|
- ✅ Made `time_period_months` Optional[int] in LiquidityMetrics model
|
|
- ✅ Updated market analysis function signatures to accept Optional[int] for time_period_months
|
|
- ✅ Fixed all remaining market analysis tests with recent dates
|
|
- ✅ Added CoordinatePoint import to test_govmap_client.py
|
|
- ✅ Fixed coordinate error message assertion
|
|
- ✅ Updated all 8 remaining fastmcp tool tests to use Deal model mocks
|
|
- ✅ Fixed `.get()` call on Deal model in analyze_market_trends (used getattr instead)
|
|
|
|
**Total tests fixed in both sessions**: All 174 tests
|
|
|
|
---
|
|
|
|
**Status**: Phase 4.1 test updates **100% COMPLETE** ✅
|
|
**Confidence**: Very High - All tests passing
|
|
**Last Updated**: 2025-01-26 (completion)
|