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':'','Average':None,'Last known':{'price':100,'timestamps':['old']}}]}) assert '<bad>' 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 '$0' 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.')