
    aje                        d dl mZ d dlZd dlmc mZ d dlm	Z	 d dl
Z
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 d d	lmZ ddZddZd dZd!dZd!dZd!dZd!dZd!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 )"    )annotationsN)Iterator)Decimal)
Connection)
TestClient)get_db)
create_app)apply_migrationsreturnr   c                 ~    t          j        dd          } t           j        | _        |                     d           | S )Nz:memory:F)check_same_threadzPRAGMA foreign_keys = ON)sqlite3connectRowrow_factoryexecuteconns    g/home/agent/.hermes/worktrees/FinanceManager-sprint0-v2/tests/unit/test_vue_dashboard_v12_acceptance.py_connectr      s8    ?:???D{DLL+,,,K    r   r   c                h     t                      }d fd}||j        t          <   t          |          S )Nr   Iterator[Connection]c               3     K    V  d S N r   s   r   override_dbz_client.<locals>.override_db   s      




r   )r   r   )r	   dependency_overridesr   r   )r   appr   s   `  r   _clientr       sE    
,,C      (3CV$c??r   Nonec                   d}|                      d|f           |                      d|f           |                      d|f           |                      d|f           |                      d|f           |                      d|f           |                      d|f           |                      d	|f           |                      d
|f           |                      d|f           |                      d|f           |                      d|f           |                      d|f           |                                  d S )N2026-05-16T12:00:00ZzINSERT INTO platforms(platform_id, name, platform_type, country, default_currency, created_at) VALUES ('p1', 'Raiffeisen', 'bank', 'CH', 'CHF', ?)zINSERT INTO platforms(platform_id, name, platform_type, country, default_currency, created_at) VALUES ('p2', 'PostFinance', 'broker', 'CH', 'CHF', ?)zINSERT INTO platforms(platform_id, name, platform_type, country, default_currency, created_at) VALUES ('p3', 'True Wealth', 'broker', 'CH', 'CHF', ?)zINSERT INTO accounts(account_id, platform_id, account_name, account_type, currency, created_at) VALUES ('cash1', 'p1', 'Privatkonto', 'cash', 'CHF', ?)zINSERT INTO accounts(account_id, platform_id, account_name, account_type, currency, created_at) VALUES ('broker1', 'p2', 'Depot', 'brokerage', 'CHF', ?)zINSERT INTO accounts(account_id, platform_id, account_name, account_type, currency, created_at) VALUES ('tw1', 'p3', 'Gesamtwert', 'managed_portfolio', 'CHF', ?)zINSERT INTO instruments(instrument_id, asset_class, name, ticker, isin, currency, created_at) VALUES ('usd1', 'etf', 'Vanguard Total Stock Market ETF', 'VTI', 'US9229087690', 'USD', ?)zINSERT INTO instruments(instrument_id, asset_class, name, ticker, isin, currency, created_at) VALUES ('chf1', 'stock', 'Swiss Demo', 'SWD', 'CH0000000000', 'CHF', ?)zINSERT INTO fx_rates(fx_rate_id, base_currency, quote_currency, rate_date, rate, provider, rate_type, quality_status, created_at) VALUES ('fx_usd', 'USD', 'CHF', '2026-05-16', '0.91', 'frankfurter', 'close', 'fresh', ?)zINSERT INTO fx_rates(fx_rate_id, base_currency, quote_currency, rate_date, rate, provider, rate_type, quality_status, created_at) VALUES ('fx_eur', 'EUR', 'CHF', '2026-05-16', '0.98', 'frankfurter', 'close', 'fresh', ?)zwINSERT INTO crypto_wallets(wallet_id, wallet_name, wallet_type, created_at) VALUES ('w1', 'Cold Wallet', 'hardware', ?)zINSERT INTO crypto_assets(asset_id, symbol, coin_name, coingecko_id, created_at) VALUES ('btc', 'BTC', 'Bitcoin', 'bitcoin', ?)zINSERT INTO crypto_holdings(crypto_holding_id, wallet_id, asset_id, quantity, verification_status, created_at) VALUES ('h1', 'w1', 'btc', '0.25', 'ok', ?))r   commit)r   nows     r   _seedr&       sa   
 CLL  f  il  hn  o  o  oLL  i  lo  kq  r  r  rLL  i  lo  kq  r  r  rLL  k  nq  ms  t  t  tLL  l  or  nt  u  u  uLL  u  x{  w}  ~  ~  ~LL  L  OR  NT  U  U  ULL  y  |  {A  B  B  BLL  o  ru  qw  x  x  xLL  o  ru  qw  x  x  xLL  K  NQ  MS  T  T  TLL  S  VY  U[  \  \  \LL  n  qt  pv  w  w  wKKMMMMMr   c            
        t                      } t          |            t          |            t          |           }ddddddddd	d
	}|                    d|                                          }|d         }d}||k    }|slt          j        d|fd||f          t          j        |          t          j        |          dz  }dd|iz  }t          t          j
        |                    d x}x}}|d         }d}||k    }|slt          j        d|fd||f          t          j        |          t          j        |          dz  }dd|iz  }t          t          j
        |                    d x}x}}|                    di ||d         dd                                          }	|                     d|	d         f                                          }
|
d         }d}||k    }|slt          j        d|fd||f          t          j        |          t          j        |          dz  }dd|iz  }t          t          j
        |                    d x}x}}|
d         }d}||k    }|slt          j        d|fd||f          t          j        |          t          j        |          dz  }dd|iz  }t          t          j
        |                    d x}x}}|
d         }d}||k    }|slt          j        d|fd||f          t          j        |          t          j        |          dz  }dd|iz  }t          t          j
        |                    d x}x}}|                    d                                          }|d         }d}||k    }|slt          j        d|fd||f          t          j        |          t          j        |          dz  }dd|iz  }t          t          j
        |                    d x}x}}|d          }d!}||k    }|slt          j        d"|fd#||f          t          j        |          t          j        |          dz  }dd|iz  }t          t          j
        |                    d x}x}}d$dd%d&d'ddd(d)d
	}|                    d|                                          }|d         }d*}||k    }|slt          j        d|fd||f          t          j        |          t          j        |          dz  }dd|iz  }t          t          j
        |                    d x}x}}|                    di ||d         dd                                          }|                     d+|d         f                                          }|d         }d&}||k    }|slt          j        d|fd||f          t          j        |          t          j        |          dz  }dd|iz  }t          t          j
        |                    d x}x}}|d         }d*}||k    }|slt          j        d|fd||f          t          j        |          t          j        |          dz  }dd|iz  }t          t          j
        |                    d x}x}}|                    d,                                          }|d         }d*}||k    }|slt          j        d|fd||f          t          j        |          t          j        |          dz  }dd|iz  }t          t          j
        |                    d x}x}}d S )-Netfbroker1usd12USD
2026-05-16initial_snapshot100z
manual usd	asset_class
account_idinstrument_idquantitycurrency
trade_datetransaction_typecost_basis_originalnote/api/positions/previewjson	fx_statusok==z%(py1)s == %(py4)spy1py4assert %(py6)spy6
amount_chfz91.00/api/positions/confirm
preview_idTrI   confirmzkSELECT fx_rate_to_chf, fx_status, gross_amount_chf, net_amount_chf FROM transactions WHERE transaction_id=?	entity_idfx_rate_to_chfz0.91gross_amount_chfz%/api/portfolio/positions/broker1:usd1statuszFX fehlt)!=)z%(py1)s != %(py4)sstockchf11CHF10z
manual chf
not_neededzISELECT fx_rate_to_chf, fx_status FROM transactions WHERE transaction_id=?z%/api/portfolio/positions/broker1:chf1)r   r
   r&   r    postr<   
@pytest_ar_call_reprcompare	_safereprAssertionError_format_explanationr   fetchoneget)r   clientreqpreview@py_assert0@py_assert3@py_assert2@py_format5@py_format7	confirmedtxdetailchfpreview_chfconfirmed_chftx_chf
detail_chfs                    r   ;test_position_confirm_resolves_cached_fx_and_chf_not_neededro   2   s	   ::D'---uT{{{T]]Fy6_bpu  FR  hz  SX  bn  o  oCkk2k==BBDDG;'4'4''''''''''4'''''''''4'''''''''''''''''''''''''''< +G+ G++++++++++ G+++++ ++++G+++++++++++++++++++++++++++4;xc;xQXYeQfsw;x;x;xyy~~  A  AI	  D  GP  Q\  G]  F_  
`  
`  
i  
i  
k  
kB)6)6))))))))))6)))))))))6)))))))))))))))))))))))))))k?"d"?d""""""""""?d"""""?""""d""""""""""""""""""""""""""" !,W,!W,,,,,,,,,,!W,,,,,!,,,,W,,,,,,,,,,,,,,,,,,,,,,,,,,,ZZ?@@EEGGF+&$&$&&&&&&&&&&$&&&&&&&&&$&&&&&&&&&&&&&&&&&&&&&&&&&&&()z)z))))))))))z)))))))))z)))))))))))))))))))))))))))!Vadrw  HT  j|  UY  co  p  pC++6S+AAFFHHK{#3|3#|3333333333#|33333#3333|333333333333333333333333333KK 8  @A#  @AU`amUn{  @A  @A  @AK  B  B  G  G  I  IM\\ehu  wB  iC  hE  F  F  O  O  Q  QF"#*s*#s**********#s*****#****s***************************+.,.,..........,.........,...........................CDDIIKKJk"2l2"l2222222222"l22222"2222l22222222222222222222222222222r   c            
        t                      } t          |            t          |            t          |           }|                    d                                          }t          d |D                       }|d         }d}||k    }|slt          j        d|fd||f          t          j	        |          t          j	        |          dz  }dd	|iz  }t          t          j        |                    d x}x}}|d
         }d}||k    }|slt          j        d|fd||f          t          j	        |          t          j	        |          dz  }dd	|iz  }t          t          j        |                    d x}x}}|d         }d}||u }|slt          j        d|fd||f          t          j	        |          t          j	        |          dz  }dd	|iz  }t          t          j        |                    d x}x}}d|d         dddddddd	}	|                    d|	          }
|
j        }d}||k    }|st          j        d|fd||f          dt          j                    v st          j        |
          rt          j	        |
          ndt          j	        |          t          j	        |          dz  }d d!|iz  }t          t          j        |                    d x}x}}g }d"}|
j        }|j        } |            }||v }|}|s d#}|
j        }|j        } |            }||v }|}|st          j        d$|fd%||f          t          j	        |          dt          j                    v st          j        |
          rt          j	        |
          ndt          j	        |          t          j	        |          t          j	        |          d&z  }d'd(|iz  }|                    |           |st          j        d$|fd)||f          t          j	        |          dt          j                    v st          j        |
          rt          j	        |
          ndt          j	        |          t          j	        |          t          j	        |          d*z  }d+d,|iz  }|                    |           t          j        |d-          i z  }d.d/|iz  }t          t          j        |                    d x}x}x}x}x}x}x}x}x}x}x}}|                    d0|d          d1dd2d3d4                                          }|d5         }d6}||k    }|slt          j        d|fd||f          t          j	        |          t          j	        |          dz  }dd	|iz  }t          t          j        |                    d x}x}}|                    d0|d          d7dd2d3|d8         d9d:                                          }|d;         }d<}||k    }|slt          j        d|fd||f          t          j	        |          t          j	        |          dz  }dd	|iz  }t          t          j        |                    d x}x}}|                     d=|d         f                                          d>         }d-}||k    }|slt          j        d|fd||f          t          j	        |          t          j	        |          dz  }dd	|iz  }t          t          j        |                    d x}x}}|                     d?|d         f                                          d>         }d-}||k    }|slt          j        d|fd||f          t          j	        |          t          j	        |          dz  }dd	|iz  }t          t          j        |                    d x}x}}|                    d@                                          }|dA         }d2}||k    }|slt          j        d|fd||f          t          j	        |          t          j	        |          dz  }dd	|iz  }t          t          j        |                    d x}x}}dB}||v }|st          j        d$|fdC||f          t          j	        |          dDt          j                    v st          j        |          rt          j	        |          ndDdEz  } dFdG| iz  }t          t          j        |                    d x}}d S )HNz/api/reference/accountsc              3  .   K   | ]}d |d         v |V  dS )zTrue WealthlabelNr   ).0as     r   	<genexpr>zStest_truewealth_is_managed_total_value_account_not_equity_target.<locals>.<genexpr>U   s0      AAA]aj%@%@a%@%@%@%@AAr   valuation_modemanual_total_valuer?   rA   rB   rE   rF   portfolio_bucket
truewealthallow_position_addsFisz%(py1)s is %(py4)sr(   r2   r*   rS   r,   r-   r.   rU   zmust be blockedr0   r:   r;   i  )z3%(py2)s
{%(py2)s = %(py0)s.status_code
} == %(py5)sblocked)py0py2py5zassert %(py7)spy7
gesamtwertzmanual totalin)z`%(py3)s in %(py11)s
{%(py11)s = %(py9)s
{%(py9)s = %(py7)s
{%(py7)s = %(py5)s.text
}.lower
}()
})py3r   r   py9py11z%(py13)spy13)zf%(py16)s in %(py24)s
{%(py24)s = %(py22)s
{%(py22)s = %(py20)s
{%(py20)s = %(py18)s.text
}.lower
}()
})py16py18py20py22py24z%(py26)spy26   zassert %(py29)spy29/api/accounts/z/value/previewz12345.67zmanual TW value)valuation_datetotal_value_chfr9   r=   rV   z/value/confirmrI   T)r   r   r9   rI   rK   rO   rg   z?SELECT COUNT(*) FROM account_value_snapshots WHERE account_id=?r   zSSELECT COUNT(*) FROM audit_log WHERE action='account_value_confirm' AND entity_id=?/api/overviewtruewealth_value_chfpostfinance_equity_value_chf)z%(py1)s in %(py3)soverviewrC   r   assert %(py5)sr   )r   r
   r&   r    r^   r<   nextrX   rY   rZ   r[   r\   rW   status_code@py_builtinslocals_should_repr_global_nametextlowerappend_format_boolopr   r]   )!r   r_   accountstwrb   rc   rd   re   rf   blocked_reqr~   @py_assert1@py_assert4@py_format6@py_format8@py_assert6@py_assert8@py_assert10@py_assert15@py_assert19@py_assert21@py_assert23@py_assert17@py_format12@py_format14@py_format25@py_format27@py_format28@py_format30ra   rg   r   @py_format4s!                                    r   @test_truewealth_is_managed_total_value_account_not_equity_targetr   P   s   ::D'---uT{{{T]]Fzz34499;;H	AAAAA	A	AB7#77#77777777777#7777777777#7777777777777777777777777777 !1\1!\1111111111!\11111!1111\111111111111111111111111111#$--$----------$-----$-------------------------------"'r,7GZ`nq  @E  Ua  wI  bf  pA  B  BKkk2kEEG%#%#%%%%%%%%%%#%%%%%%%%%%%%7%%%%%7%%%%%%%%%%#%%%%%%%%%%%%%%%%%%%%%%%%%%%YY<Y7<Y<-Y--//Y<//YYYYY>YW\Y\EWYEWEWEYEYY>EY3YYYYYYYYYYYY</YYYYY<YYYYYYYYYYY7YYYYY7YYYYYY<YYYY-YYYY/YYYYYYYYYYYYYYYYYYYYYYYYYYY>EYYYYYY>YYYYYYYYYYYWYYYYYWYYYYYY\YYYYEWYYYYEYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYkkK2l+;KKKeq  GQ  [l  Sm  Smk  n  n  s  s  u  uG;/</<//////////</////////<///////////////////////////MR-=MMMgs  IS  ]n  ~E  FR  ~S  `d  Ue  Ue  f  f  k  k  m  mIX-+-+----------+---------+---------------------------<<Y\^_k\l[nooxxzz{|}  C  BC  C}  BC  C  C  C  C  C  C  C  C  C  C}  BC  C  C  C  C  C}  C  C  C  C  BC  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C<<mprs  qA  pC  D  D  M  M  O  O  PQ  R  W  VW  W  R  VW  W  W  W  W  W  W  W  W  W  W  R  VW  W  W  W  W  W  R  W  W  W  W  VW  W  W  W  W  W  W  W  W  W  W  W  W  W  W  W  W  W  W  W  W  W  W  W  W  W  W  Wzz/**//11H*+9z9+z9999999999+z99999+9999z999999999999999999999999999)5)X5555555555)X55555)55555555555X55555X55555555555555555555555555555r   c           	     :   t                      }t          |           t          |           ddi G fdd          dd lmc m} |                     |dfd           t          |          }|                    d           d         }d}||k    }|slt          j
        d|fd	||f          t          j        |          t          j        |          d
z  }dd|iz  }t          t          j        |                    d x}x}}|                    ddddd                                          }	d         }d}||k    }|slt          j
        d|fd	||f          t          j        |          t          j        |          d
z  }dd|iz  }t          t          j        |                    d x}x}}|	d         d         d         }d}||k    }|slt          j
        d|fd	||f          t          j        |          t          j        |          d
z  }dd|iz  }t          t          j        |                    d x}x}}|	d         }d}||u }|slt          j
        d|fd||f          t          j        |          t          j        |          d
z  }dd|iz  }t          t          j        |                    d x}x}}d}t!          |	          }
|
j        } |            }||v}|st          j
        d|fd||f          t          j        |          dt%          j                    v st          j        t                     rt          j        t                     nddt%          j                    v st          j        |	          rt          j        |	          ndt          j        |
          t          j        |          t          j        |          dz  }d d!|iz  }t          t          j        |                    d x}x}x}
x}}d S )"Ncountr   c                  &    e Zd ZdZddd	 fdZdS )
etest_provider_search_endpoint_returns_candidates_and_no_provider_call_on_render.<locals>.FakeProviderfake_providerNr1   querystrr1   
str | Nonec               `    dxx         dz  cc<   ddl m}  |d |pddddd	d
ddd
  
        gS )Nr   r   r   CatalogSearchResultr(   zVanguard Total StockUS9229087690VTINYSEARCAr,   r   highfake)isintickerexchangetrading_currencyprovider
confidencesource"jarvis_finance.market_data.catalogr   )selfr   r1   r   calleds       r   searchzltest_provider_search_endpoint_returns_candidates_and_no_provider_call_on_render.<locals>.FakeProvider.searchq   s    7OOOq OOONNNNNN''k.BUDZaox}  IS  fk  vE  RX  ag  h  h  h  i  ir   r   r   r1   r   __name__
__module____qualname__namer   )r   s   r   FakeProviderr   o   sO        BF 	i 	i 	i 	i 	i 	i 	i 	i 	i 	ir   r   _provider_search_providersc                                   gS r   r   )r   s   r   <lambda>zatest_provider_search_endpoint_returns_candidates_and_no_provider_call_on_render.<locals>.<lambda>w   s    LLNNCS r   r   r?   rA   rB   rE   rF    /api/instruments/provider-searchr(   r   r,   r1   r   r5   r;   r   
candidatesr   selection_requiredTr{   r}   api_keynot in)zh%(py1)s not in %(py10)s
{%(py10)s = %(py8)s
{%(py8)s = %(py6)s
{%(py6)s = %(py3)s(%(py4)s)
}.lower
}()
}r   payload)rC   r   rD   rF   py8py10zassert %(py12)spy12)r   r
   r&   ,jarvis_finance.services.manual_entry_serviceservicesmanual_entry_servicesetattrr    r^   rX   rY   rZ   r[   r\   rW   r<   r   r   r   r   r   )monkeypatchr   svcr_   rb   rc   rd   re   rf   r   @py_assert5@py_assert7@py_assert9@py_format11@py_format13r   r   s                  @@r   Otest_provider_search_endpoint_returns_candidates_and_no_provider_call_on_renderr   k   s   ::D'---uT{{{q\Fi i i i i i i i i i ?>>>>>>>>9;S;S;S;STTTT]]F
JJ'?a?a?a?akk<SXchv{C|C|k}}  C  C  E  EG'?a?a?a?a< #H-66-6666666666-66666-6666666666666666666666666666666'(0D0(D0000000000(D00000(0000D0000000000000000000000000000CLL0L.0..0009000000000009000000900000000000C00000C000000000000000000000000L0000.00000000000000000000000000000000000000r   c                 D   t                      } t          |            t          |            d}|                     d|f           |                     d|f           |                     d|f           |                                  t          |           }|                    di                                           }|d         }d}||k    }|slt          j	        d	|fd
||f          t          j
        |          t          j
        |          dz  }dd|iz  }t          t          j        |                    d x}x}}|d         }d}||k    }|slt          j	        d	|fd
||f          t          j
        |          t          j
        |          dz  }dd|iz  }t          t          j        |                    d x}x}}|d         }d}||k    }|slt          j	        d	|fd
||f          t          j
        |          t          j
        |          dz  }dd|iz  }t          t          j        |                    d x}x}}|                     d                                          d         }d}||k    }|slt          j	        d	|fd
||f          t          j
        |          t          j
        |          dz  }dd|iz  }t          t          j        |                    d x}x}}|                    dddd                                          }	|	d         }d}||k    }|slt          j	        d	|fd
||f          t          j
        |          t          j
        |          dz  }dd|iz  }t          t          j        |                    d x}x}}|                     d                                          d         }d}||k    }|slt          j	        d	|fd
||f          t          j
        |          t          j
        |          dz  }dd|iz  }t          t          j        |                    d x}x}}|                     d                                          d         }d}||k    }|slt          j	        d	|fd
||f          t          j
        |          t          j
        |          dz  }dd|iz  }t          t          j        |                    d x}x}}|                     d                                          d         }d}||k    }|slt          j	        d	|fd
||f          t          j
        |          t          j
        |          dz  }dd|iz  }t          t          j        |                    d x}x}}d S )Nr#   zINSERT INTO accounts(account_id, platform_id, account_name, account_type, currency, created_at) VALUES ('review_acc', 'p2', 'True Wealth Review Brokerage', 'brokerage', 'CHF', ?)a  INSERT INTO transactions(transaction_id, transaction_type, account_id, instrument_id, trade_date, quantity, gross_amount_original, net_amount_original, currency_original, source_type, is_confirmed, quality_status, notes, created_at) VALUES ('review_tx', 'initial_position_snapshot', 'review_acc', 'usd1', '2026-05-16', '1', '1', '1', 'USD', 'broker_import_reviewed_snapshot', 1, 'ok', 'review artifact', ?)a  INSERT INTO transactions(transaction_id, transaction_type, account_id, instrument_id, trade_date, quantity, gross_amount_original, net_amount_original, currency_original, source_type, is_confirmed, quality_status, notes, created_at) VALUES ('manual_tx', 'initial_position_snapshot', 'broker1', 'chf1', '2026-05-16', '1', '1', '1', 'CHF', 'vue_manual_position', 1, 'ok', 'real manual', ?)z%/api/cleanup/review-artifacts/previewr;   r   r   r?   rA   rB   rE   rF   transactionsmanual_positions_preservedz<SELECT is_active FROM accounts WHERE account_id='review_acc'r   z%/api/cleanup/review-artifacts/confirmTzacceptance cleanuprK   r9   rO   rg   zCSELECT is_voided FROM transactions WHERE transaction_id='review_tx'zCSELECT is_voided FROM transactions WHERE transaction_id='manual_tx')r   r
   r&   r   r$   r    rW   r<   rX   rY   rZ   r[   r\   r]   )
r   r%   r_   ra   rb   rc   rd   re   rf   rg   s
             r   Vtest_cleanup_preview_and_confirm_archives_review_artifacts_preserving_manual_positionsr      s   ::D'---uT{{{
 CLL  F  IL  HN  O  O  OLL  j  mp  lr  s  s  sLL  W  Z]  Y_  `  `  `KKMMMT]]FkkAkKKPPRRG:#!#!##########!#########!###########################>"'a'"a''''''''''"a'''''"''''a'''''''''''''''''''''''''''/05A50A55555555550A5555505555A555555555555555555555555555<<VWW``bbcdejijjeijjjjjjjjjjjeijjjjjjejjjjijjjjjjjjjjjjjjjjjjjjjjjjjjjjCVZdxJyJyzz  B  BIX-+-+----------+---------+---------------------------<<VWW``bbcdejijjeijjjjjjjjjjjeijjjjjjejjjjijjjjjjjjjjjjjjjjjjjjjjjjjjjj<<]^^ggiijklqpqqlpqqqqqqqqqqqlpqqqqqqlqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqq<<]^^ggiijklqpqqlpqqqqqqqqqqqlpqqqqqqlqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqr   c            
        t                      } t          |            t          |            t          |           }ddddddddd	d
	}|                    d|                                          }|                    di ||d         dd           |                    di                                           }|d         }d}||u }|slt          j        d|fd||f          t          j        |          t          j        |          dz  }dd|iz  }	t          t          j
        |	                    d x}x}}|                    ddddd                                          }
|
d         }d}||k    }|slt          j        d|fd||f          t          j        |          t          j        |          dz  }dd|iz  }	t          t          j
        |	                    d x}x}}|                     d                                           d!         }d"}||k    }|slt          j        d|fd||f          t          j        |          t          j        |          dz  }dd|iz  }	t          t          j
        |	                    d x}x}}|                     d#                                          d!         }d"}||k    }|slt          j        d|fd||f          t          j        |          t          j        |          dz  }dd|iz  }	t          t          j
        |	                    d x}x}}|                     d$           |                                  |                    d%i                                           }|d         }d}||u }|slt          j        d|fd||f          t          j        |          t          j        |          dz  }dd|iz  }	t          t          j
        |	                    d x}x}}|                    d&ddd'd                                          }|d         }d}||k    }|slt          j        d|fd||f          t          j        |          t          j        |          dz  }dd|iz  }	t          t          j
        |	                    d x}x}}|                     d(           |                                  |                    d%i                                           }|d         }d}||u }|slt          j        d|fd||f          t          j        |          t          j        |          dz  }dd|iz  }	t          t          j
        |	                    d x}x}}|                    d&ddd)d                                          }|d         }d}||k    }|slt          j        d|fd||f          t          j        |          t          j        |          dz  }dd|iz  }	t          t          j
        |	                    d x}x}}|                    d|                                          }|                    di ||d         dd           |                     d*           |                                  |                    di                                           }|d         }d+}||u }|slt          j        d|fd||f          t          j        |          t          j        |          dz  }dd|iz  }	t          t          j
        |	                    d x}x}}d S ),NrQ   r)   rR   rS   rT   r-   r.   rU   z	bad inputr0   r:   r;   rH   rI   TrJ   z*/api/positions/broker1:chf1/remove/previewsafe_to_remover{   r}   rB   rE   rF   z*/api/positions/broker1:chf1/remove/confirm	ENTFERNENzwrong position)rK   confirmation_textr9   rO   rg   r?   rA   zLSELECT COUNT(*) FROM transactions WHERE is_voided=1 AND instrument_id='chf1'r   r   zESELECT COUNT(*) FROM audit_log WHERE action='position_remove_confirm'a  INSERT INTO transactions(transaction_id, transaction_type, account_id, instrument_id, trade_date, quantity, gross_amount_original, net_amount_original, currency_original, fx_rate_to_chf, fx_status, source_type, is_confirmed, quality_status, notes, created_at) VALUES ('legacy_snapshot', 'initial_snapshot', 'broker1', 'usd1', '2026-05-16', '1', '10', '10', 'USD', '0.91', 'ok', 'manual_initial_snapshot', 1, 'ok', 'legacy manual snapshot', '2026-05-16T12:00:00Z')z*/api/positions/broker1:usd1/remove/previewz*/api/positions/broker1:usd1/remove/confirmzlegacy cleanupa  INSERT INTO transactions(transaction_id, transaction_type, account_id, instrument_id, trade_date, quantity, gross_amount_original, net_amount_original, currency_original, fx_rate_to_chf, fx_status, source_type, is_confirmed, quality_status, notes, created_at) VALUES ('manual_adjustment_snapshot', 'manual_adjustment', 'broker1', 'usd1', '2026-05-16', '1', '10', '10', 'USD', '0.91', 'ok', 'manual_dashboard', 1, 'ok', 'manual adjustment snapshot', '2026-05-16T12:00:00Z')zmanual adjustment cleanupa~  INSERT INTO transactions(transaction_id, transaction_type, account_id, instrument_id, trade_date, quantity, gross_amount_original, net_amount_original, currency_original, source_type, is_confirmed, quality_status, notes, created_at) VALUES ('hist_tx', 'buy', 'broker1', 'chf1', '2026-05-17', '1', '10', '10', 'CHF', 'vue_manual_position', 1, 'ok', 'history', '2026-05-17T12:00:00Z')F)r   r
   r&   r    rW   r<   rX   rY   rZ   r[   r\   r   r]   r$   )r   r_   r`   ra   remove_previewrb   rc   rd   re   rf   donelegacy_previewlegacy_doneadjustment_previewadjustment_donepreview2r~   s                    r   Dtest_remove_position_voids_single_manual_snapshot_but_blocks_historyr	     ss	   ::D'---uT{{{T]]F!Vadrw  HT  j|  UY  cn  o  oCkk2k==BBDDG
KK(/l#/lW\EZgk/l/l/lKmmm[[!MTV[WW\\^^N*+3t3+t3333333333+t33333+3333t333333333333333333333333333;;CVZq|  GW  KX  KX;  Y  Y  ^  ^  `  `D>([(>[((((((((((>[(((((>(((([(((((((((((((((((((((((((((<<fggpprrstuzyzzuyzzzzzzzzzzzuyzzzzzzuzzzzyzzzzzzzzzzzzzzzzzzzzzzzzzzzz<<_``iikklmnsrssnrsssssssssssnrssssssnssssrssssssssssssssssssssssssssss 	LL  c  d  d  dKKMMM[[!MTV[WW\\^^N*+3t3+t3333333333+t33333+3333t333333333333333333333333333++J]a  yD  N^  R_  R_+  `  `  e  e  g  gKx /K/ K////////// K///// ////K/////////////////////////// 	LL  l  m  m  mKKMMM%QXZ[[``bb./747/47777777777/477777/77774777777777777777777777777777kk"Nae  }H  Rm  Vn  Vnk  o  o  t  t  v  vO8$33$3333333333$33333$3333333333333333333333333333333 {{3#{>>CCEEHv{{Sk  squx  sq  IQ  R^  I_  lp  sq  sq  sq{  Hr  Hr  HrLL  R  S  S  SKKMMMkkFRkPPUUWWG#$--$----------$-----$---------------------------------r   c                 
   t                      } t          |            t          |            t          |           }|                    ddddd                                          }|                    dddd|d         d	d
                                          }|d         }|                    d| dd	dd                                          }|d         }|j        } |            }|j        }	d}
 |	|
          }|sdt          j	        |          t          j	        |          t          j	        |          t          j	        |	          t          j	        |
          t          j	        |          dz  }t          t          j        |                    d x}x}x}x}	x}
}|                    dd	dd                                          }d}|d         }|j        } |            }||v }|st          j        d|fd||f          t          j	        |          t          j	        |          t          j	        |          t          j	        |          dz  }dd|iz  }t          t          j        |                    d x}x}x}x}}|                     d                                          d         }d}||k    }|slt          j        d|fd||f          t          j	        |          t          j	        |          d z  }d!d"|iz  }t          t          j        |                    d x}x}}|                    d#d$d%d&d'dd(                                          }|                    d)d$d%d&d'd|d         d	d*                                          }|d         }|                    d+| d,d	d-d                                          }|d.         }d/}||k    }|slt          j        d|fd||f          t          j	        |          t          j	        |          d z  }d!d"|iz  }t          t          j        |                    d x}x}}|                     d0                                          d         }d1}||k    }|slt          j        d2|fd3||f          t          j	        |          t          j	        |          d z  }d!d"|iz  }t          t          j        |                    d x}x}}d S )4Nz/api/wallets/previewzEmpty Walletr   new)r   wallet_typer9   r;   z/api/wallets/confirmrI   T)r   r  r9   rI   rK   rL   z/api/wallets/z/delete/confirmemptyr   messageu   wallet gelöschtzassert %(py11)s
{%(py11)s = %(py7)s
{%(py7)s = %(py5)s
{%(py5)s = %(py3)s
{%(py3)s = %(py1)s.lower
}()
}.startswith
}(%(py9)s)
})rC   r   r   r   r   r   z/api/wallets/w1/delete/confirmarchivedeaktiviertr   )zD%(py1)s in %(py8)s
{%(py8)s = %(py6)s
{%(py6)s = %(py4)s.lower
}()
})rC   rD   rF   r   zassert %(py10)sr   z9SELECT is_active FROM crypto_wallets WHERE wallet_id='w1'r   r?   rA   rB   rE   rF   z/api/accounts/previewzAnderes KontozManual Broker	brokeragerT   )platform_nameaccount_nameaccount_typer5   r9   z/api/accounts/confirm)r  r  r  r5   r9   rI   rK   r   z/deactivate/confirmz
not neededrO   rg   zSELECT COUNT(*) FROM audit_log WHERE action IN ('wallet_create_confirm','wallet_delete_confirm','wallet_deactivate_confirm','account_create_confirm','account_deactivate_confirm')   )>=)z%(py1)s >= %(py4)s)r   r
   r&   r    rW   r<   r   
startswithrX   rZ   r[   r\   rY   r   r]   )r   r_   wallet_previewwalletwiddeletedrb   rd   r   r   r   r   r   nonemptyrc   r   r   @py_format9r   re   rf   account_previewaccountaiddeactivateds                            r   Btest_wallet_and_account_create_deactivate_delete_rules_are_auditedr"     s;   ::D'---uT{{{T]]F[[!7~fpz  ?A  ?A[  B  B  G  G  I  IN[[/~^hrw  HV  Wc  Hd  qu  7v  7v[  w  w  |  |  ~  ~F

Ckk>#>>>QU_fEgEgkhhmmooG9D#D##%%D%0D1CD001CDDDDDDDDDDDD#DDDD%DDDD0DDDD1CDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD{{;d\eBfBf{ggllnnH7HY/7/5755777=77777777777=777777=7777/77775777777777777777777777777777777777777<<STT]]__`abgfggbfgggggggggggbfggggggbggggfggggggggggggggggggggggggggggkk"9Ra  tC  U`  ns  }B  AC  ACk  D  D  I  I  K  KOkk1/kz  MX  fk  uz  JY  Zf  Jg  tx  9y  9yk  z  z      A  AG
+
C++GsGGGZ^htNuNu+vv{{}}Kx /K/ K////////// K///// ////K///////////////////////////<<  M  N  N  W  W  Y  Y  Z[  \  a  `a  a  \  `a  a  a  a  a  a  a  a  a  a  a  \  `a  a  a  a  a  a  \  a  a  a  a  `a  a  a  a  a  a  a  a  a  a  a  a  a  a  a  a  a  a  a  a  a  a  a  a  a  a  a  a  a  ar   c                <   t                      }t          |           t          |            G d d           G d d          dd lmc m} |                     |dfd           t          |          }|                    dd	d
dddddd          	                                }|d         }t          |          }d}||k    }|st          j        d|fd||f          dt          j                    v st          j        t                    rt          j        t                    ndt          j        |          t          j        |          t          j        |          dz  }	dd|	iz  }
t#          t          j        |
                    d x}x}x}}|d         d         }|d         }d
}||k    }|slt          j        d|fd||f          t          j        |          t          j        |          dz  }dd|iz  }t#          t          j        |                    d x}x}}|d         }d}||k    }|slt          j        d|fd||f          t          j        |          t          j        |          dz  }dd|iz  }t#          t          j        |                    d x}x}}|d          }d}||k    }|slt          j        d|fd||f          t          j        |          t          j        |          dz  }dd|iz  }t#          t          j        |                    d x}x}}|d!         }|s:d"d#t          j        |          iz  }t#          t          j        |                    d }|d$         }d%}||k    }|slt          j        d|fd||f          t          j        |          t          j        |          dz  }dd|iz  }t#          t          j        |                    d x}x}}|d&         }d}||k    }|slt          j        d|fd||f          t          j        |          t          j        |          dz  }dd|iz  }t#          t          j        |                    d x}x}}|d'         }d}||k    }|slt          j        d|fd||f          t          j        |          t          j        |          dz  }dd|iz  }t#          t          j        |                    d x}x}}|d(         }d)}||k    }|slt          j        d|fd||f          t          j        |          t          j        |          dz  }dd|iz  }t#          t          j        |                    d x}x}}|d*         }|s:d"d#t          j        |          iz  }t#          t          j        |                    d }|d+         }d}||k    }|slt          j        d|fd||f          t          j        |          t          j        |          dz  }dd|iz  }t#          t          j        |                    d x}x}}|d,         }d-}||k    }|slt          j        d|fd||f          t          j        |          t          j        |          dz  }dd|iz  }t#          t          j        |                    d x}x}}|d.         }d/}||k    }|slt          j        d|fd||f          t          j        |          t          j        |          dz  }dd|iz  }t#          t          j        |                    d x}x}}g }d0}|d1         }||v }|}|rd2}|d1         }||v }|}|st          j        d3|fd4||f          t          j        |          t          j        |          d5z  }d6d7|iz  }|                    |           |r`t          j        d3|fd8||f          t          j        |          t          j        |          d9z  }d:d;|iz  }|                    |           t          j        |d          i z  }d<d=|iz  }t#          t          j        |                    d x}x}x}x}x}x}x}}|d>         }d?d@h}||v }|slt          j        d3|fdA||f          t          j        |          t          j        |          dz  }dd|iz  }t#          t          j        |                    d x}x}}d S )BNc                       e Zd ZdZddd	dZdS )
Xtest_provider_search_deduplicates_enriches_filters_and_ranks_goog.<locals>.FakeProviderAopenfigiNr   r   r   r1   r   c                   ddl m}  |di dddddd	d
ddddddd	dddddddddddddddddd d!d" |d d#d$d%dd&d'dd(d&d)ddd*d*+          gS ),Nr   r   )NrQ   zALPHABET INC-CL Cr   US02079K1079r   GOOGr   NASDAQr   r,   r   r&  provider_symbolBBG009S3NB30provider_marketcountryUSr   mediumr   evidence_notezprimary listing
last_price175.12price_currency
price_dater-   security_typeCommon Stockexchange_namezNasdaq Global SelectmicXNASrQ   zALPHABET INC - CDRCA02079K3055NEOCADBBGCDRCACDR)r   r   r   r   r   r+  r-  r.  r   r   r1  r6  r   r   r   r1   r   s       r   r   z_test_provider_search_deduplicates_enriches_filters_and_ranks_goog.<locals>.FakeProviderA.search   s   NNNNNN##  Q  Q  Q^^  Qdjdj  Qu}u}  Q  QV  QV  Q  ak  ak  Q  }K  }K  Q  ]e  ]e  Q  os  os  Q  @H  @H  Q  Q[  Q[  Q  k|  k|  Q  IQ  IQ  Q  bg  bg  Q  t@  t@  Q  P^  P^  Q  nD  nD  Q  JP  JP  Q##D'3Gnekv{  OT  _i  {C  UZ  dh  u}  FP  `e  uz  {  {  { r   r   r   r   r   r   FakeProviderAr%     s:        BF 	 	 	 	 	 	 	 	r   rB  c                       e Zd ZdZddd	dZdS )
Xtest_provider_search_deduplicates_enriches_filters_and_ranks_goog.<locals>.FakeProviderBfinnhubNr   r   r   r1   r   c                   ddl m}  |di dddddd	d
ddddddd	ddddddddddddddddddd d! |d d"d#d$d%d&dd'd(dd)*          gS )+Nr   r   )NrQ   Alphabet Inc Class Cr   r(  r   r)  r   r*  r   r,   r   rE  r+  r-  r.  r/  r   r0  r   r1  zsymbol lookupr2  z175.10r4  r5  r-   r6  r7  r8  Nasdaqr9  r:  rQ   zGoogol Technology Co Ltd8118HKEXHKDHKlowzweak name match)r   r   r   r   r.  r   r   r1  r   rA  s       r   r   z_test_provider_search_deduplicates_enriches_filters_and_ranks_goog.<locals>.FakeProviderB.search   s   NNNNNN##  z  z  zP^P^  zgmgm  z  yA  yA  z  TY  TY  z  dm  dm  z  E  E  z  W_  W_  z  im  im  z  zB  zB  z  KT  KT  z  ds  ds  z  @H  @H  z  Y^  Y^  z  kw  kw  z  GU  GU  z  em  em  z  sy  sy  z##D'3MV\gm  AF  QZ  dh  uz  CL  \m  n  n  n r   r   r   r   r   r   FakeProviderBrD     s:        BF 	 	 	 	 	 	 	 	r   rN  r   r   c                 ,                               gS r   r   )rB  rN  s   r   r   zStest_provider_search_deduplicates_enriches_filters_and_ranks_goog.<locals>.<lambda>   s    MMOOUbUbUdUdCe r   r   rQ   r)  r,   r*  r/  T)r1   r   r5   r   r.  main_listing_onlyhide_cdr_adr_derivativesr;   r   r   r?   )z0%(py4)s
{%(py4)s = %(py0)s(%(py2)s)
} == %(py7)slen)r   r   rD   r   zassert %(py9)sr   r   rA   rB   rE   rF   r   r(  r   r8  assert %(py1)srC   r9  r:  r5   r.  r6  r7  r2  r4  r5  r-   r+  r,  r&  r   rE  r   )z%(py3)s in %(py6)s)r   rF   z%(py8)sr   )z%(py11)s in %(py14)s)r   py14z%(py16)sr   zassert %(py19)spy19confidence_label	EindeutigWahrscheinlich)z%(py1)s in %(py4)s)r   r
   r&   r   r   r   r   r    rW   r<   rR  rX   rY   r   r   r   rZ   r[   r\   r   r   )r   r   r   r_   r   r   rc   r   r   r   @py_format10googrb   rd   re   rf   @py_format2r   r   @py_assert13@py_assert12r  @py_format15@py_format17@py_format18@py_format20rB  rN  s                             @@r   Atest_provider_search_deduplicates_enriches_filters_and_ranks_googrb     s   ::D'---uT{{{               ?>>>>>>>>9;e;e;e;e;efffT]]Fkk<SZeky~  MU  bf  }A  _c  Dd  Ddk  e  e  j  j  l  lG|$*3$%%**%**********%************3*****3******$****%*********************************< #D>#V#>V##########>V#####>####V###########################<)>)<>))))))))))<>)))))<))))>)))))))))))))))))))))))))))
'x'x''''''''''x'''''''''x'''''''''''''''''''''''''''                         ; & ;&          ;&     ;    &                           
$u$u$$$$$$$$$$u$$$$$$$$$u$$$$$$$$$$$$$$$$$$$$$$$$$$$	?"d"?d""""""""""?d"""""?""""d""""""""""""""""""""""""""" 2N2 N2222222222 N22222 2222N222222222222222222222222222 !*U*!U**********!U*****!****U***************************------------------------------------------------!"4n4"n4444444444"n44444"4444n444444444444444444444444444KK:Kj)K:))KKKKKiK4
;KKi;K.KKKKKKKKKKKK:)KKKKK:KKKK)KKKKKKKKKKKKKKKKKKKKKKKKKKKi;KKKKKKiKKKK;KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK"#F5E'FF#'FFFFFFFFFFF#'FFFFFF#FFFF'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFr   c                (   t                      }t          |           t          |            G d d           G d d          dd lmc m} |                     |dfd           t          |          }|                    dd	d
dd          	                                }|d         }|s:ddt          j        |          iz  }t          t          j        |                    d }|d         }dg}||k    }|slt          j        d|fd||f          t          j        |          t          j        |          dz  }	dd|	iz  }
t          t          j        |
                    d x}x}}d}t          |          }||v}|st          j        d|fd||f          t          j        |          dt!          j                    v st          j        t                    rt          j        t                    nddt!          j                    v st          j        |          rt          j        |          ndt          j        |          dz  }
dd|
iz  }t          t          j        |                    d x}x}}d }t          |          }||v}|st          j        d|fd||f          t          j        |          dt!          j                    v st          j        t                    rt          j        t                    nddt!          j                    v st          j        |          rt          j        |          ndt          j        |          dz  }
dd|
iz  }t          t          j        |                    d x}x}}d S )!Nc                       e Zd ZdZddd	dZdS )
btest_provider_search_suppresses_raw_provider_errors_when_candidate_exists.<locals>.WorkingProviderr&  Nr   r   r   r1   r   c               B    ddl m}  |d |pddddddd	dd
dd	          gS )Nr   r   rQ   rG  r(  r)  r*  r,   r&  r/  r   )	r   r   r   r   r   r+  r.  r   r   r   rA  s       r   r   zitest_provider_search_suppresses_raw_provider_errors_when_candidate_exists.<locals>.WorkingProvider.search  s    NNNNNN''k.DWF\cq  {A  LT  gl  wA  SY  cg  tz  CM  N  N  N  O  Or   r   r   r   r   r   WorkingProviderre    sB        BF 	O 	O 	O 	O 	O 	O 	O 	Or   rg  c                       e Zd ZdZddd	dZdS )
atest_provider_search_suppresses_raw_provider_errors_when_candidate_exists.<locals>.BrokenProviderbroken_providerNr   r   r   r1   r   c                    t          d          )Nz1upstream HTTP 500 secret-ish raw provider failure)RuntimeErrorr   r   r1   s      r   r   zhtest_provider_search_suppresses_raw_provider_errors_when_candidate_exists.<locals>.BrokenProvider.search  s    RSSSr   r   r   r   r   r   BrokenProviderri    sB         BF 	T 	T 	T 	T 	T 	T 	T 	Tr   rn  r   r   c                 ,                               gS r   r   )rn  rg  s   r   r   z[test_provider_search_suppresses_raw_provider_errors_when_candidate_exists.<locals>.<lambda>  s    OODUDUWeWeWgWgCh r   r   rQ   r)  r,   r   r;   r   rS  rC   warningsue   Datenquelle teilweise eingeschränkt: Ein Provider lieferte keine Daten; Treffer stammt aus openfigi.r?   rA   rB   rE   rF   zHTTP 500r   )z4%(py1)s not in %(py6)s
{%(py6)s = %(py3)s(%(py4)s)
}r   r   )rC   r   rD   rF   assert %(py8)sr   zraw provider failure)r   r
   r&   r   r   r   r   r    rW   r<   rX   rZ   r[   r\   rY   r   r   r   r   )r   r   r   r_   r   rb   r[  rc   rd   re   rf   r   r  rn  rg  s                @@r   Itest_provider_search_suppresses_raw_provider_errors_when_candidate_existsrr    s   ::D'---uT{{{O O O O O O O OT T T T T T T T
 ?>>>>>>>>9;h;h;h;h;hiiiT]]Fkk<SZeky~CCk  A  A  F  F  H  HG<                         :  L  $K  #L  L  #L  L  L  L  L  L  L  L  L  L  L  #L  L  L  L  L  L  L  L  L  L  #L  L  L  L  L  L  L  L  L  L  L  L  L  L  L  L  L  L  L  L  L  L  L  L  L  L  L  L)S\\):\)))))))))):\))))):)))))))))))S)))))S))))))))))))))))))))))))\)))))))))))))))))))))))))))!5W5!5555555555!55555!55555555555555555555555555555W55555W55555555555555555555555555555555555r   c                H  
 t                      }t          |           t          |            G d d          
dd lmc m} |                     |d
fd           t          |          }|                    dddd	
          	                                }|d         }g }||k    }|slt          j        d|fd||f          t          j        |          t          j        |          dz  }dd|iz  }	t          t          j        |	                    d x}x}}|d         }dg}||k    }|slt          j        d|fd||f          t          j        |          t          j        |          dz  }dd|iz  }	t          t          j        |	                    d x}x}}d S )Nc                       e Zd ZdZddd	dZdS )
Ptest_provider_search_no_candidates_has_clear_user_warning.<locals>.EmptyProviderempty_providerNr   r   r   r1   r   c                   g S r   r   rm  s      r   r   zWtest_provider_search_no_candidates_has_clear_user_warning.<locals>.EmptyProvider.search"  s    Ir   r   r   r   r   r   EmptyProviderru     s:        BF 	 	 	 	 	 	 	 	r   rx  r   r   c                                   gS r   r   )rx  s   r   r   zKtest_provider_search_no_candidates_has_clear_user_warning.<locals>.<lambda>&  s    MMOOCT r   r   rQ   DOESNOTEXIST)r1   r   r;   r   r?   rA   rB   rE   rF   rp  u,   Keine verlässlichen Providerdaten gefunden.)r   r
   r&   r   r   r   r   r    rW   r<   rX   rY   rZ   r[   r\   )r   r   r   r_   r   rb   rc   rd   re   rf   rx  s             @r   9test_provider_search_no_candidates_has_clear_user_warningr{    s"   ::D'---uT{{{       
 ?>>>>>>>>9;T;T;T;TUUUT]]Fkk<SZesCtCtkuuzz||G< &B& B&&&&&&&&&& B&&&&& &&&&B&&&&&&&&&&&&&&&&&&&&&&&&&&&:R#Q"RR"RRRRRRRRRRR"RRRRRRRRRR"RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRr   c            
     *   t                      } t          |            t          |            d}|                     d||f           |                                  t          |           }ddddddd	d
dd	}|                     d                                          d         }|                    d|                                          }|d         }|j	        }d} ||          }	|	ssdt          j        |          t          j        |          t          j        |          t          j        |	          dz  }
t          t          j        |
                    d x}x}x}}	|                     d                                          d         }||k    }|st          j        d|fd||f          t          j        |          dt          j                    v st          j        |          rt          j        |          nddz  }dd|iz  }t          t          j        |                    d x}}|                    di ||d         dd                                          }|                     d|d          f                                          }|d!         }d}||k    }|slt          j        d|fd"||f          t          j        |          t          j        |          d#z  }d$d%|iz  }t          t          j        |                    d x}x}}|                     d&|d'         f                                          }t%          |          }d(d)d*dd+d,d-}||k    }|st          j        d|fd.||f          d/t          j                    v st          j        t$                    rt          j        t$                    nd/d0t          j                    v st          j        |          rt          j        |          nd0t          j        |          t          j        |          d1z  }d2d3|iz  }t          t          j        |                    d x}x}}|                     d4|d'         f                                          }|d5         }d6}||k    }|slt          j        d|fd"||f          t          j        |          t          j        |          d#z  }d$d%|iz  }t          t          j        |                    d x}x}}|d7         }d}||k    }|slt          j        d|fd"||f          t          j        |          t          j        |          d#z  }d$d%|iz  }t          t          j        |                    d x}x}}|d8         }d,}||k    }|slt          j        d|fd"||f          t          j        |          t          j        |          d#z  }d$d%|iz  }t          t          j        |                    d x}x}}|                    d9                                          }t)          d: |D                       }|d7         }d}||k    }|slt          j        d|fd"||f          t          j        |          t          j        |          d#z  }d$d%|iz  }t          t          j        |                    d x}x}}|d;         }d<}||k    }|slt          j        d|fd"||f          t          j        |          t          j        |          d#z  }d$d%|iz  }t          t          j        |                    d x}x}}|d=         }d }||u}|slt          j        d>|fd?||f          t          j        |          t          j        |          d#z  }d$d%|iz  }t          t          j        |                    d x}x}}|                     d@                                          d         }dA}||k    }|slt          j        d|fd"||f          t          j        |          t          j        |          d#z  }d$d%|iz  }t          t          j        |                    d x}x}}d S )BNr#   a  
        INSERT INTO instrument_catalog_entries(catalog_entry_id, asset_class, name, normalized_name, isin, ticker, exchange, trading_currency, instrument_currency, provider, provider_symbol, provider_market, country, source, source_confidence, last_price, price_currency, price_date, created_at, updated_at)
        VALUES ('cat_goog', 'stock', 'ALPHABET INC-CL C', 'alphabet inc cl c', 'US02079K1079', 'GOOG', 'NASDAQ', 'USD', 'USD', 'openfigi', 'BBG009S3NB30', 'NASDAQ', 'US', 'openfigi', 'high', '175.12', 'USD', '2026-05-16', ?, ?)
    rQ   r)   cat_googr+   r,   r-   r.   r/   zprovider candidate)	r1   r2   candidate_idr4   r5   r6   r7   r8   r9   z:SELECT COUNT(*) FROM instruments WHERE isin='US02079K1079'r   r:   r;   summaryALPHABETLassert %(py7)s
{%(py7)s = %(py3)s
{%(py3)s = %(py1)s.startswith
}(%(py5)s)
}rC   r   r   r   r?   )z%(py1)s == %(py3)sbeforer   r   r   rH   rI   TrJ   zPSELECT instrument_id, currency_original FROM transactions WHERE transaction_id=?rL   currency_originalrA   rB   rE   rF   zvSELECT ticker, isin, exchange, currency, provider_symbol, data_provider_primary FROM instruments WHERE instrument_id=?r3   r)  r(  r*  r,  r&  )r   r   r   r5   r+  data_provider_primary)z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} == %(py6)sdictinst)r   rC   r   rF   rq  r   zISELECT close, currency, provider FROM market_prices WHERE instrument_id=?closer3  r5   r   z/api/equity/positionsc              3  2   K   | ]}|d          dk    |V  dS )r   r)  Nr   )rs   rows     r   ru   z\test_provider_candidate_preview_confirm_materializes_instrument_and_audit.<locals>.<genexpr>I  s0      EECS]f-D-DC-D-D-D-DEEr   rO   Bewertetmarket_value_chf)is not)z%(py1)s is not %(py4)sz>SELECT COUNT(*) FROM audit_log WHERE action='position_confirm'r   )r   r
   r&   r   r$   r    r]   rW   r<   r  rX   rZ   r[   r\   rY   r   r   r   r  r^   r   )r   r%   r_   r`   r  ra   rb   rd   r   r   r   r   r   rg   rh   rc   re   rf   r  r   r  priceequitygoog_rows                           r   Itest_provider_candidate_preview_confirm_materializes_instrument_and_auditr  /  sq   ::D'---uT{{{
 CLL  s   	KKMMMT]]F!Jdguz  KW  m  X]  g{  |  |C\\VWW``bbcdeFkk2k==BBDDG94(44((444444444444(44444444444444444444444444444444<<TUU^^``abcmcgmmmmmmmmmmmcgmmmmmmcmmmmmmmmmmmgmmmmmmgmmmmmmmmmmmmmmmmmmmmmmmmmmmm4;xc;xQXYeQfsw;x;x;xyy~~  A  AI	hkt  vA  lB  kD  
E  
E  
N  
N  
P  
PB!"+e+"e++++++++++"e+++++"++++e+++++++++++++++++++++++++++<<  Q  TV  Wf  Tg  Si  j  j  s  s  u  uD::  uFNPXfk  AO  jt  u  u  u:  u  u  u  u  u  u  u  u  u  u  u:  u  u  u  u  u  u  u  u  u  u  u  u  u4  u  u  u  u  u4  u  u  u  u  u  u  u  u  u  u  u  u  u  u  u  u  u  u  u  u  u  u  u  u:  u  u  u  u  u  u  u  u  u  u  u  u  u  u  u  u  u  u  u  u  u  u  u  u  u  u  u  u  u  u  u  uLLdgijygzf|}}  G  G  I  IE>%X%>X%%%%%%%%%%>X%%%%%>%%%%X%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*
*
**********
*********
***************************ZZ/005577FEE6EEEEEHJ(5(5((((((((((5(((((((((5(((((((((((((((((((((((((((H++++++++++++++++++++++++++++++++++++++++++++++++&'3t3't3333333333't33333'3333t333333333333333333333333333<<XYYbbddefglkllgklllllllllllgkllllllgllllkllllllllllllllllllllllllllllllr   c                    t                      } t          |            t          |            |                     dd           |                     d           |                                  t          |           }|                    d                                          }|d         d         }d}||k    }|slt          j	        d|fd	||f          t          j
        |          t          j
        |          d
z  }dd|iz  }t          t          j        |                    d x}x}}|d         d         }d}||k    }|slt          j	        d|fd	||f          t          j
        |          t          j
        |          d
z  }dd|iz  }t          t          j        |                    d x}x}}|d         }|j        }d} ||          }	|	ssdt          j
        |          t          j
        |          t          j
        |          t          j
        |	          dz  }
t          t          j        |
                    d x}x}x}}	d S )N5UPDATE crypto_assets SET notes=? WHERE asset_id='btc')z{"coingecko": {"market_cap_rank": 1, "market_cap": "2000000000000", "volume_24h": "50000000000", "change_24h_pct": "2.50", "change_7d_pct": "5.00", "homepage": "https://bitcoin.org", "image_url": "https://example.test/btc.png"}}zINSERT INTO crypto_prices(crypto_price_id, asset_id, coingecko_id, price_currency, price, provider, fetched_at, quality_status) VALUES ('cp1', 'btc', 'bitcoin', 'CHF', '80000', 'coingecko_cache', '2026-05-16T12:00:00Z', 'fresh')/api/crypto/positions/btccoingecko_infomarket_cap_rankr   r?   rA   rB   rE   rF   homepagezhttps://bitcoin.orgread_only_notezLive-Modus optionalr  r  )r   r
   r&   r   r$   r    r^   r<   rX   rY   rZ   r[   r\   r  )r   r_   ri   rb   rc   rd   re   rf   r   r   r   s              r   Ftest_crypto_detail_exposes_cached_coingecko_info_without_provider_callr  P  s   ::D'---uT{{{LLH  Kt  u  u  uLL  x  y  y  yKKMMMT]]FZZ34499;;F"#$56;!;6!;;;;;;;;;;6!;;;;;6;;;;!;;;;;;;;;;;;;;;;;;;;;;;;;;;"#J/H3HH/3HHHHHHHHHHH/3HHHHHH/HHHH3HHHHHHHHHHHHHHHHHHHHHHHHHHHH"#E#.E/DE../DEEEEEEEE#EEEE.EEEE/DEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEr   c                 >   t                      } t          |            t          |            |                     dd           |                                  t          |           }|                    d                                          }|d         d         }d }||u }|slt          j	        d|fd||f          t          j
        |          t          j
        |          dz  }d	d
|iz  }t          t          j        |                    d x}x}}|d         d         }d }||u }|slt          j	        d|fd||f          t          j
        |          t          j
        |          dz  }d	d
|iz  }t          t          j        |                    d x}x}}d S )Nr  )zZ{"coingecko": {"homepage": "javascript:alert(1)", "image_url": "data:image/svg+xml,evil"}}r  r  r  r{   r}   rB   rE   rF   	image_url)r   r
   r&   r   r$   r    r^   r<   rX   rY   rZ   r[   r\   )r   r_   ri   rb   rc   rd   re   rf   s           r   2test_crypto_detail_sanitizes_cached_coingecko_urlsr  _  s   ::D'---uT{{{LLH  Kj  k  k  kKKMMMT]]FZZ34499;;F"#J/747/47777777777/477777/77774777777777777777777777777777"#K08D80D88888888880D8888808888D88888888888888888888888888888r   )r   r   )r   r   r   r   )r   r   r   r!   )r   r!   )%
__future__r   builtinsr   _pytest.assertion.rewrite	assertionrewriterX   collections.abcr   r   decimalr   r   fastapi.testclientr   jarvis_finance.api.dependenciesr   jarvis_finance.api.mainr	   !jarvis_finance.storage.migrationsr
   r   r    r&   ro   r   r   r   r	  r"  rb  rr  r{  r  r  r  r   r   r   <module>r     s
   " " " " " "               $ $ $ $ $ $              ) ) ) ) ) ) 2 2 2 2 2 2 . . . . . . > > > > > >         $3 3 3 3<6 6 6 661 1 1 10r r r r,#. #. #. #.La a a a.*G *G *G *GZ6 6 6 64S S S S$m m m mBF F F F	9 	9 	9 	9 	9 	9r   