Hotel-Rate-Radar / test_accuracy.py
CodeAntidote's picture
Fix Google competitor pricing lookup and starting-rate parsing
75eaa9a verified
Raw History Blame Contribute Delete
6.15 kB
import ast,sys,types
from pathlib import Path
from unittest.mock import Mock
from datetime import date,timedelta
sys.path.insert(0,str(Path(__file__).resolve().parent))
r=types.ModuleType('requests');r.RequestException=type('RequestException',(Exception,),{});sys.modules['requests']=r
import verified_rates as v
D=date.today()+timedelta(days=1)
room=lambda price:{'name':'Room, 1 Queen Bed','num_guests':2,'rate_per_night':{'extracted_before_taxes_fees':price},'link':'https://example.com'}
prop={'name':v.HOTELS[0],'address':'619 Riverside Avenue, Santa Cruz','featured_prices':[{'source':'Booking.com','rooms':[room(100)]},{'source':'booking.com','rooms':[room(110)]},{'source':'Expedia.com','rooms':[room(120)]}],'rate_per_night':{'extracted_before_taxes_fees':70}}
o=v.parse_offers(prop,'1 Queen','test');selected,avg,_=v.select_offers(o)
assert len(selected)==2 and avg==110
assert not v.parse_offers({'prices':[{'source':'Expedia','rate_per_night':{'extracted_lowest':88}}]},'1 Queen','test')
assert v.room_category('Suite, 1 Queen Bed') is None
assert v.room_category('Room, 2 Queen Beds')=='2 Queen Plus'
assert not v.matches({'name':v.HOTELS[0],'address':'Huntington Beach'},v.HOTELS[0])
resp=Mock();resp.json.return_value=dict(prop,search_parameters={'check_in_date':D.isoformat(),'check_out_date':(D+timedelta(days=1)).isoformat(),'adults':2,'children':0,'currency':'USD'})
r.get=Mock(return_value=resp)
assert len(v.google_offers(v.HOTELS[0],D,'test')[0])==1
resp.json.return_value=dict(prop,search_parameters={});assert not v.google_offers(v.HOTELS[0],D,'test')[0]
nodes=[]
for n in ast.parse(Path(__file__).with_name('app.py').read_text()).body:
if isinstance(n,ast.With):break
if isinstance(n,ast.Import) and any(a.name=='gradio' for a in n.names):continue
nodes.append(n)
g={};exec(compile(ast.Module(body=nodes,type_ignores=[]),'app.py','exec'),g)
pd=g['pd'];empty=pd.DataFrame()
g['get_weather_map']=lambda:{};g['get_ticketmaster_events_range']=lambda *a:({},'Unavailable');g['get_tomtom_traffic']=lambda:(None,[],'Unavailable')
args=['Selected date',D.isoformat(),g['DEFAULT_HOTEL'],g['DEFAULT_MARKET'],False,4,None,g['DEFAULT_OTA'],g['DEFAULT_COMPS'],g['ROOM_PROFILE'],None,None,'None / normal day','Normal',59,399,3,'Selected time','3:00 PM','','',0,False,False]
result=g['analyze_selection'](*args);assert 'Reference estimate' in result[0] and '$85' in result[0]
args[6]=99; result=g['analyze_selection'](*args);assert len(result)==8 and 'entered' in result[3].lower()
assert g['occupancy_adjustment'](None)==0 and g['pickup_adjustment'](None)==0
assert g['room_type_recommendations'](100,g['ROOM_PROFILE'],None,59,399,3,99).iloc[0]['Current rate']=='—'
args[0]='30-day forecast';args[4]=True;result=g['analyze_selection'](*args);assert 'Enable 30-day' in result[0]
print('PASS: nested rooms, no Google aggregate double count, seller aliases, real arithmetic mean, missing tax/room rejection, suite exclusion, wrong city, date echo mismatch, empty market, blank demand, no invented current room prices, bulk quota gate.')
import tempfile
with tempfile.TemporaryDirectory() as tmp:
v.HISTORY_PATH=str(Path(tmp)/'history.db')
v.CACHE.clear()
good=[dict(source='Expedia',price=123.45,tax_basis='Before tax',room='1 Queen',policy='Unverified',official=False,checked_at='2026-09-21 10:00 UTC',link='https://example.com')]
v.google_offers=lambda *a:(good,'OK')
v.shop(D,fresh=True)
v.google_offers=lambda *a:([],'Unavailable: network')
failed,_=v.shop(D,fresh=True)
assert not failed['own_sources'] and not failed['competitors']
assert 'Last known price: $123.45' in failed['audit'][0]['Status']
assert '2026-09-21 10:00 UTC' in failed['audit'][0]['Status']
assert v.last_known(v.HOTELS[0],D+timedelta(days=1),'1 Queen') is None
assert v.last_known(v.HOTELS[0],D,'3 Queen') is None
assert v.last_known(v.HOTELS[0],D,'hotel-starting-v2')['price']==123.45
print('PASS: saved-price fallback, original timestamp, date/room isolation, stale prices excluded from current averages.')
assert g['_safe_float']('inf') is None
assert g['_safe_float']('nan') is None
card=g['source_cards']({'audit':[{'Hotel':'<bad>','Average':None,'Last known':{'price':100,'timestamps':['old']}}]})
assert '&lt;bad&gt;' in card and 'Last known' in card and '$100' in card
print('PASS: finite numeric inputs and escaped historical snapshot cards.')
from datetime import datetime
fixed=datetime(2026,9,21,23,0,tzinfo=g['TZ'])
late=g['hourly_context'](fixed.date(),'Live now',15,'','',0,now=fixed)
assert late['adjustment']==-.10
assert g['hourly_context'](fixed.date(),'Live now',15,'','',0,now=fixed,late_reduction=0)['adjustment']==0
f=g['ROOM_PROFILE'].copy();f.loc[0,'Rooms left']=1
regular=g['room_type_recommendations'](100,f,None,59,599,3)
late_rooms=g['room_type_recommendations'](100,f,None,59,599,3,late_high_traffic=True)
assert g['_safe_float'](late_rooms.iloc[0]['Recommended BAR']) < g['_safe_float'](regular.iloc[0]['Recommended BAR'])
assert late_rooms.iloc[0]['Availability impact']=='-3%'
assert g['_safe_float'](g['room_type_recommendations'](269,g['ROOM_PROFILE'],None,59,599,3).iloc[-1]['Recommended BAR'])==409
print('PASS: late-hour cap, disable policy, low-inventory/high-traffic reduction, ASI reference $409 room.')
args[0]='Selected date';args[4]=False;args[6]=0
result=g['analyze_selection'](*args)
assert 'Reference estimate' in result[0] and '<strong>$0</strong>' not in result[0]
print('PASS: zero manual rate rejected; reference estimate available without live quotes.')
listing={'prices':[{'source':'Booking.com','rate_per_night':{'extracted_before_taxes_fees':100}},{'source':'Expedia','rate_per_night':{'extracted_before_taxes_fees':120}}],'rate_per_night':{'extracted_before_taxes_fees':95}}
o=v.starting_offers(listing,'test')
assert len(o)==2 and v.select_offers(o)[1]==110
unknown=v.starting_offers({'rate_per_night':{'extracted_lowest':123}},'test')
assert unknown[0]['price']==123 and v.select_offers(unknown)[1] is None
print('PASS: hotel starting prices without room labels, no aggregate duplication, unknown tax excluded from pre-tax averages.')