
    @&j%                        d dl mZ d dlmZ d dlmZ d dlmZ d dlm	Z	m
Z
mZmZmZmZmZ d dlmZ d dlmZ  G d d	          Z G d
 d          Z G d d          Zd ZddZddZddZddZddZddZddZdS )    )annotations)Path)data)page_13_equity_manage)ProviderCandidateexport_mapping_decision_packgenerate_mapping_candidatesrank_candidaterecalculate_candidate_rankingsreject_mapping_candidateselect_mapping_candidate)connect_memory)apply_migrationsc                       e Zd ZdZddZd ZdS )StaticLookupProviderstaticNc                    |pi | _         d S N)candidates_by_isin)selfr   s     5tests/unit/test_true_wealth_mapping_candidates_c3d.py__init__zStaticLookupProvider.__init__   s    "4":    c               R    t          | j                            |g                     S r   )listr   get)r   isinnametickerexchangecurrencys         r   lookupzStaticLookupProvider.lookup   s#    D+//b99:::r   r   )__name__
__module____qualname__r   r   r"    r   r   r   r      s<        D; ; ; ;; ; ; ; ;r   r   c                      e Zd Zd Zd ZdS )FakeTabc                    | S r   r&   )r   s    r   	__enter__zFakeTab.__enter__   s    r   c                    dS NFr&   )r   argss     r   __exit__zFakeTab.__exit__"   s    ur   N)r#   r$   r%   r*   r.   r&   r   r   r(   r(      s2              r   r(   c                      e Zd Zd Zd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zd Zd Zd Zd Zd Zd Zd Zd ZdS )FakeStc                    d S r   r&   r   r-   kwargss      r   titlezFakeSt.title'         r   c                    d S r   r&   r2   s      r   captionzFakeSt.caption(   r5   r   c                    d S r   r&   r2   s      r   warningzFakeSt.warning)   r5   r   c                    d S r   r&   r2   s      r   	subheaderzFakeSt.subheader*   r5   r   c                    d S r   r&   r2   s      r   writezFakeSt.write+   r5   r   c                    d S r   r&   r2   s      r   successzFakeSt.success,   r5   r   c                    d S r   r&   r2   s      r   errorzFakeSt.error-   r5   r   c                    d S r   r&   r2   s      r   infozFakeSt.info.   r5   r   c                    d S r   r&   r2   s      r   dividerzFakeSt.divider/   r5   r   c                    d S r   r&   r2   s      r   	dataframezFakeSt.dataframe0   r5   r   c                    d S r   r&   r2   s      r   tablezFakeSt.table1   r5   r   c                    d |D             S )Nc                *    g | ]}t                      S r&   r(   ).0_s     r   
<listcomp>zFakeSt.tabs.<locals>.<listcomp>2   s    #>#>#>!GII#>#>#>r   r&   )r   labelss     r   tabszFakeSt.tabs2   s    #>#>v#>#>#>>r   c                    |r|d         nd S )Nr   r&   )r   labeloptionsr3   s       r   	selectboxzFakeSt.selectbox3   s    :Y'!**UY3Yr   c                .    |                     dd          S )Nvalue )r   r2   s      r   
text_inputzFakeSt.text_input4   s    &**Wb2I2I+Ir   c                    dS )NrX   r&   r2   s      r   	text_areazFakeSt.text_area5   s    r   c                    dS )Nz
2025-12-31r&   r2   s      r   
date_inputzFakeSt.date_input6   s    ,,r   c                    dS r,   r&   r2   s      r   checkboxzFakeSt.checkbox7   s    r   c                    t                      S r   rL   r2   s      r   expanderzFakeSt.expander8   s    		)9r   c                    dS r,   r&   r2   s      r   buttonzFakeSt.button9   s    eer   N)r#   r$   r%   r4   r7   r9   r;   r=   r?   rA   rC   rE   rG   rI   rQ   rU   rY   r[   r]   r_   ra   rc   r&   r   r   r0   r0   &   s        ***,,,,,,...***,,,***))),,,...***>>>YYYIII333>>>55599933333r   r0   c                     t                      } t          |            |                     d           |                     d           |                     d           |                     d           | S )NzINSERT INTO platforms(platform_id,name,platform_type,default_currency,created_at) VALUES('p1','True Wealth','broker','CHF','now')zINSERT INTO accounts(account_id,platform_id,account_name,account_type,currency,created_at) VALUES('a1','p1','TW','brokerage','CHF','now')zINSERT INTO instruments(instrument_id,asset_class,name,ticker,isin,exchange,currency,created_at) VALUES('inst1','ETF','Global Equity ETF','GETF','CH0000000001',NULL,'USD','now')aA  INSERT INTO transactions(transaction_id,transaction_type,account_id,instrument_id,trade_date,quantity,currency_original,fx_status,source_type,is_confirmed,quality_status,created_at) VALUES('tx1','initial_position_snapshot','a1','inst1','2025-12-31','1','USD','missing','broker_import_reviewed_snapshot',1,'warning','now'))r   r   execute)conns    r   
setup_connrg   <   s    DTLL  U  V  V  VLL  ]  ^  ^  ^LL  E  F  F  FLL  U  V  V  VKr   returnNonec                 &   dddddddd} t          dd	ddddd
dd	  	        }t          dddddddd          }t          | |d          }t          | |d          }|j        |j        k    sJ d|j        v sJ d|j        v sJ d|j        v sJ d S )NCH0000000001ETFGlobal Equity ETFGETFSWXCHF)r   asset_classr   r   r    r!   trading_currencyopenfigiGETF.SWetfactiveopenfigi_isin_mapping	providerprovider_symbolr    r!   r   r   rq   instrument_statusevidence_sourceyahooNYSEUSDstockyahoo_finance_search)ry   rz   r    r!   r   r   rq   r|      )candidate_countz
ISIN passtu   Währung passtcurrency_mismatch)r   r
   ranking_scoreranking_reason
risk_flags)instgoodbad	good_rankbad_ranks        r   9test_candidate_ranking_prioritizes_isin_currency_exchanger   F   s)   "5BUaguz  IN  di  j  jDj)V[fk  sF  M[  in  BJ  \s  t  t  tD
Wfv`el  GU  cj  |R  S  S  SCtT1===IdC;;;H"X%;;;;;933333y77777("5555555r   c                 0   t                      } |                     d           t          dt          dddddddd	d
	  	        t          dddddddd	d
	  	        gi          }t	          | |           t          |           }t          j        |           }|d         dk    sJ d |D             dhk    sJ t          |d         d                   t          |d         d                   k    sJ |d         d         sJ |d         d         dk    sJ d S )NzYUPDATE instruments SET currency='CHF', trading_currency='CHF' WHERE instrument_id='inst1'rk   rs   zGETF.USr~   r   rm   ru   rv   rw   rx   rt   ro   rp   ry   multiple_listings_same_isin   c                    h | ]
}|d          S )review_statusr&   )rM   rs     r   	<setcomp>zUtest_same_isin_multiple_listings_remain_review_required_and_sorted.<locals>.<setcomp>]   s    ---1Ao---r   needs_manual_reviewr   r   r   candidate_provider_symbol)	rg   re   r   r   r	   r   r   !get_instrument_mapping_candidatesint)rf   ry   summaryrowss       r   Btest_same_isin_multiple_listings_remain_review_required_and_sortedr   R   s   <<DLLlmmm#^:ySYdi  qD  KY  gl  @H  Zq  	r  	r  	r:ySXch  pC  JX  fk  G  Yp  	q  	q  	q6 %  H  x8888,T22G1$77D01Q6666-----2G1HHHHHtAw'((CQ0H,I,IIIII7#$$$$7./9<<<<<<r   c                   t                      }t          dt          ddddddddd	
	  	        gi          }t          ||           t	          |           | dz  dz  }t          ||d          }|                    d          |d         dk    sJ |d         dk    sJ |d         du sJ dv sJ g d}t          fd|D                       rJ d S )Nrk   rs   rt   ro   rp   rm   ru   rv   rw   rx   r   runtime_exportszdecision_pack.md   )output_pathtop_nutf-8encodinginstrument_countr   candidate_rowstop_candidates_presentTzRanking Reason)quantityamountmarket_value
kontostandportfolioanteilzprice:c              3  h   K   | ],}|                                                                  v V  -d S r   )lower)rM   tokentexts     r   	<genexpr>zLtest_decision_pack_runtime_only_contains_no_amount_fields.<locals>.<genexpr>r   s8      HHU5;;==DJJLL0HHHHHHr   )rg   r   r   r	   r   r   	read_textany)tmp_pathrf   ry   outr   	forbiddenr   s         @r   9test_decision_pack_runtime_only_contains_no_amount_fieldsr   c   sT   <<D#^:ySXch  pC  JX  fk  G  Yp  	q  	q  	q6 %  H  x8888"4(((
&
&);
;C*4SJJJG=='=**D%&!++++#$))))+,4444t####aaaIHHHHiHHHHHHHHHHr   c                    t                      } dD ]!}|                     d|dddd||ddf	           "t          d	t          d
ddddd	ddd	  	        gi          }t	          | |           |                     d                                          d         }t          | |d           |                     d                                          d         dk    sJ |                     d                                          d         dk    sJ |                     d                                          d         dk    sJ |                     d                                          d         dk    sJ d S )N)missing_provider_symbolambiguous_provider_mappingcandidate_review_requiredzINSERT INTO alerts(alert_id,priority,category,entity_type,entity_id,rule_id,message,status,created_at) VALUES(?,?,?,?,?,?,?,?,?)warnungmarket_data
instrumentinst1rv   nowrk   rs   rt   ro   rp   rm   ru   rw   rx   r   <SELECT candidate_id FROM instrument_price_mapping_candidatescandidate_idzmanual dashboard confirmationr   notezKSELECT COUNT(*) AS c FROM audit_log WHERE action='select_mapping_candidate'cr   zSELECT COUNT(*) AS c FROM alerts WHERE status='active' AND rule_id IN ('missing_provider_symbol','ambiguous_provider_mapping','candidate_review_required')r   zmSELECT provider_symbol, exchange, trading_currency FROM instrument_price_mappings WHERE instrument_id='inst1'rz   zTSELECT COUNT(*) AS c FROM instrument_catalog_entries WHERE provider_symbol='GETF.SW')rg   re   r   r   r	   fetchoner   )rf   rulery   r   s       r   Ftest_candidate_confirmation_resolves_mapping_alerts_and_writes_catalogr   u   sw   <<Df o o  X  [_  aj  ly  {G  IP  RV  X\  ^f  hm  Zn  	o  	o  	o  	o#^6GQ[mv  BG  RW  ^q  xF  TY  mu  G^  7_  7_  7_  6`  %a  b  bHx8888<< ^__hhjjkyzLTCbcccc<<effooqqruvz{{{{{<<  u  v  v      A  A  BE  F  JK  K  K  K  K<<  H  I  I  R  R  T  T  Uf  g  kt  t  t  t  t<<nooxxzz{~  DE  E  E  E  E  E  Er   c            
        t                      } t          dt          ddddd          gi          }t          | |           |                     d                                          d	         }t          | |d
           |                     d                                          d         dk    sJ |                     d|f                                          d         dk    sJ d S )Nrk   rs   rt   ro   rp   ry   rz   r    r!   r   r   r   r   zwrong listingr   zKSELECT COUNT(*) AS c FROM audit_log WHERE action='reject_mapping_candidate'r   r   zRSELECT review_status FROM instrument_price_mapping_candidates WHERE candidate_id=?r   rejected)rg   r   r   r	   re   r   r   )rf   ry   r   s      r   %test_candidate_rejection_writes_auditr      s=   <<D#^6GQ[mv  BG  RW  ^l  7m  7m  7m  6n  %o  p  pHx8888<< ^__hhjjkyzLT?SSSS<<effooqqruvz{{{{{<<lo{n}~~  H  H  J  J  KZ  [  _i  i  i  i  i  i  ir   c            
         t                      } t          dt          ddddd          gi          }t          | |           t	          |            t          j        t                      |            d S )Nrk   rs   rt   ro   rp   r   r   )rg   r   r   r	   r   r   renderr0   )rf   ry   s     r   Ctest_dashboard_review_ui_renders_ranked_candidates_without_live_apir      s    <<D#^6GQ[mv  BG  RW  ^l  7m  7m  7m  6n  %o  p  pHx8888"4((( 400000r   c                     t          d          } |                                 sJ |                     d          }d|v sJ d|v sJ t          d                                          rJ d S )Nz3docs/personal-finance-cashflow-budgeting-backlog.mdr   r   zBacklog onlyzDo not implementz#src/jarvis_finance/personal_finance)r   existsr   )docr   s     r   Dtest_personal_finance_backlog_document_exists_without_implementationr      s    
D
E
EC::<<<=='=**DT!!!!%%%%9::AACCCCCCCr   N)rh   ri   )
__future__r   pathlibr   jarvis_finance.dashboardr   jarvis_finance.dashboard.pagesr   %jarvis_finance.market_data.candidatesr   r   r	   r
   r   r   r   jarvis_finance.storage.databaser   !jarvis_finance.storage.migrationsr   r   r(   r0   rg   r   r   r   r   r   r   r   r&   r   r   <module>r      s   " " " " " "       ) ) ) ) ) ) @ @ @ @ @ @                  ; : : : : : > > > > > >; ; ; ; ; ; ; ;       4 4 4 4 4 4 4 4,  	6 	6 	6 	6= = = ="I I I I$E E E Ei i i i1 1 1 1D D D D D Dr   