
    YajG,                        d dl 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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 )    )annotations)IteratorN)
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    2tests/unit/test_dashboard_functional_actions_v2.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 )Nz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', '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 instruments(instrument_id, asset_class, name, ticker, isin, currency, created_at) VALUES ('inst1', 'stock', 'Demo Equity', 'DEMO', '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-17', '0.91', 'fixture', 'close', 'fresh', ?)zINSERT INTO market_prices(market_price_id, instrument_id, price_date, close, currency, provider, quality_status, created_at) VALUES ('mp1', 'inst1', '2026-05-16', '12', 'CHF', 'local', 'ok', ?)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, gross_amount_chf, net_amount_chf, source_type, is_confirmed, quality_status, notes, created_at) VALUES ('buy1', 'buy', 'broker1', 'inst1', '2026-05-16', '10', '100', '100', 'CHF', '1', 'not_needed', '100', '100', 'fixture', 1, 'ok', 'opening buy', ?)zINSERT INTO cash_balances(cash_balance_id, account_id, balance_date, currency, amount_original, fx_rate_to_chf, amount_chf, source_type, quality_status, created_at) VALUES ('cb1', 'cash1', '2026-05-16', 'CHF', '1000', '1', '1000', 'fixture', 'ok', ?)zwINSERT INTO crypto_wallets(wallet_id, wallet_name, wallet_type, created_at) VALUES ('w1', 'Cold Wallet', 'hardware', ?)z{INSERT INTO crypto_wallets(wallet_id, wallet_name, wallet_type, created_at) VALUES ('w2', 'Exchange Wallet', 'exchange', ?)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.25000000', '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  k  nq  ms  t  t  tLL  l  or  nt  u  u  uLL  |  B  ~D  E  E  ELL  k  nq  ms  t  t  tLL  U  X[  W]  ^  ^  ^LL  T  WZ  V\  ]  ]  ]LL  N  QT  PV  W  W  WLL  K  NQ  MS  T  T  TLL  O  RU  QW  X  X  XLL  S  VY  U[  \  \  \LL  t  wz  v|  }  }  }KKMMMMMr   c            	     z   t                      } t          |            t          |            t          |           }ddddddddd	}|                    d
|                                          }|d                             d          sJ |                     d                                          d         dk    sJ |                    di ||d         dd                                          }|d         dk    sJ d |                     d          	                                D             }|d         dk    sJ |d         dk    sJ |                     d                                          }|d d          dk    sJ |                     d                                          d         dk    sJ d S )Nbtcw1w2
0.10000000
0.00010000transfer
2026-05-17zmove to exchange)asset_id	wallet_idtarget_wallet_idquantityfee_quantitytransaction_typeeffective_datenote/api/crypto/actions/previewjsonsummaryzCrypto TransferzLSELECT quantity FROM crypto_holdings WHERE wallet_id='w1' AND asset_id='btc'r   z
0.25000000/api/crypto/actions/confirm
preview_idTr9   confirmstatus	confirmedc                ,    i | ]}|d          |d         S )r-   r/   r   .0rows     r   
<dictcomp>zctest_crypto_transfer_moves_between_wallets_preserves_total_minus_fee_and_audits.<locals>.<dictcomp>F   s5      ^  ^  ^cK #j/  ^  ^  ^r   zDSELECT wallet_id, quantity FROM crypto_holdings WHERE asset_id='btc'z
0.14990000zvSELECT from_wallet_id, to_wallet_id, quantity, fee_quantity FROM crypto_transactions WHERE transaction_type='transfer')r&   r'   r(   r)   zESELECT COUNT(*) FROM audit_log WHERE action='crypto_transfer_confirm'   )
r   r	   r#   r   postr6   
startswithr   fetchonefetchall)r   clientrequestpreviewr=   holdingstransfer_rows          r   Otest_crypto_transfer_moves_between_wallets_preserves_total_minus_fee_and_auditsrM   1   sS   ::D'---uT{{{T]]F  $&&"	 	G kk7gkFFKKMMG9(():;;;;;<<fggpprrstu  zF  F  F  F  F9  AB7  ABZabnZo  }A  AB  AB  AB  C  C  H  H  J  JIX+---- ^  ^T\\  KQ  >R  >R  >[  >[  >]  >]  ^  ^  ^HD>\))))D>\))))<<  !Y  Z  Z  c  c  e  eL?FFFFF<<_``iikklmnrsssssssr   c                 2   t                      } t          |            t          |            t          |           }|                    ddddddddd	
          }|j        dk    sJ |                    dddddddddddd

          }|j        dk    sJ d S )Nr4   r%   r&   r'   z-0.1r*   r+   bad)r,   r-   r.   r/   r1   r2   r3   r5     r8   z0.30ztoo muchpreview_testT)
r,   r-   r.   r/   r0   r1   r2   r3   r9   r;   )r   r	   r#   r   rD   status_code)r   rH   negative	oversizeds       r   :test_crypto_transfer_blocks_negative_or_oversized_quantityrV   N   s	   ::D'---uT{{{T]]F{{8E`dz~  MS  is  GS  ]b  @c  @c{  d  dH3&&&&9Uae{  NS  eh  ~H  \h  r|  LZ  gk  Al  Al  m  mI C''''''r   c            	     >   t                      } t          |            t          |            t          |           }ddddddddd	}|                    d
|                                          }|d                             d          sJ |d         dk    sJ |                    di ||d         dd                                          }|d         dk    sJ |                     d                                          }|d d          dk    sJ |                     d                                          d         dk    sJ |                     d                                          d         dk    sJ i |ddd}|                    d
|                                          }|                    di ||d         dd                                          }|d         dk    sJ |                    d
i |dd d          }	|	j	        d!k    sJ d S )"Nbroker1:inst1cash1412CHFr+   1zpartial sale)position_idcash_account_idr/   price_originalcurrency
trade_datefees_originalr3   z /api/equity/actions/sell/previewr5   r7   Verkauf
amount_chfz47.00z /api/equity/actions/sell/confirmr9   Tr:   r<   r=   zqSELECT transaction_type, quantity, net_amount_original, fee_original FROM transactions WHERE notes='partial sale')sellz-447r]   zMSELECT COUNT(*) FROM cash_balances WHERE source_type LIKE 'vue_equity_sale:%'r   rC   zASELECT COUNT(*) FROM audit_log WHERE action='equity_sell_confirm'6z	full sale)r/   r3   z0.1oversellrP   )
r   r	   r#   r   rD   r6   rE   r   rF   rS   )
r   rH   salerJ   r=   txfullfull_previewfull_confirmedblockeds
             r   Dtest_equity_sale_partial_full_and_oversell_rules_with_audit_and_cashrp   Y   s   ::D'---uT{{{T]]F*wTWko  ~C  S_  ru  M  N  NDkk<4kHHMMOOG9((33333< G++++>  FD  FD\cdp\q  C  FD  FD  FD  E  E  J  J  L  LIX+----	  J  
K  
K  
T  
T  
V  
VBaaa5-----<<ghhqqsstuvz{{{{{<<[\\eegghijnooooo9d9[999D;;A;MMRRTTL[[!C  KNT  KNamnza{  IM  KN  KN  KN[  O  O  T  T  V  VN(#{2222kk<CrdCrX]gqCrCrCrkssG#%%%%%%r   c            
     d   t                      } t          |            t          |            t          |           }ddddddddd	d
	}|                    d|                                          }|d                             d          sJ |d         dk    sJ |                    di ||d         dd                                          }|d         dk    sJ |                     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 )NrX   rY   100r\   355rQ   r+   zquarterly dividend)	r^   r_   gross_amountra   	swiss_taxforeign_taxother_deductionspayment_dater3   z$/api/equity/actions/dividend/previewr5   r7   	Dividendere   z60.00z$/api/equity/actions/dividend/confirmr9   Tr:   r<   r=   zSELECT transaction_type, quantity, gross_amount_original, tax_original, net_amount_original FROM transactions WHERE notes='quarterly dividend')dividendNrr   4060zJSELECT COUNT(*) FROM cash_balances WHERE source_type='vue_equity_dividend'r   rC   zSELECT SUM(CAST(quantity AS REAL)) FROM transactions WHERE account_id='broker1' AND instrument_id='inst1' AND coalesce(is_voided,0)=0
   zESELECT COUNT(*) FROM audit_log WHERE action='equity_dividend_confirm')	r   r	   r#   r   rD   r6   rE   r   rF   )r   rH   r{   rJ   r=   rA   s         r   Xtest_equity_dividend_writes_income_cash_net_tax_fields_and_audit_without_quantity_changer   r   sP   ::D'---uT{{{T]]F.7\aot  DH  Y\  ru  GS  ]q  r  rHkk@xkPPUUWWG9((55555< G++++B  JLH  JLdklxdy  GK  JL  JL  JL  M  M  R  R  T  TIX+----
,,  h  i  i  r  r  t  tCqqq6:::::<<deennppqrswxxxxx<<  `  a  a  j  j  l  l  mn  o  su  u  u  u  u<<_``iikklmnrsssssssr   c            
     :   t                      } t          |            t          |            t          |           }ddddddddd	d
	}|                    d|                                          }|                    di ||d         dd                                          }|d         dk    sJ |                     d                                          d         dk    sJ |                     d                                          d         dk    sJ d S )Nstockbroker1inst12r\   r+   buy24z
inline buy)	asset_class
account_idinstrument_idr/   ra   rb   r1   cost_basis_originalr3   z/api/positions/previewr5   z/api/positions/confirmr9   Tr:   r<   r=   zBSELECT transaction_type FROM transactions WHERE notes='inline buy'r   z>SELECT COUNT(*) FROM audit_log WHERE action='position_confirm'rC   )r   r	   r#   r   rD   r6   r   rF   )r   rH   r   rJ   r=   s        r   Rtest_equity_inline_buy_reuses_position_confirm_with_prefilled_instrument_and_auditr      sH   ::D'---uT{{{T]]F!Wbesx  IU  kp  IM  Wc  d  dCkk2k==BBDDG4;xc;xQXYeQfsw;x;x;xyy~~  A  AIX+----<<\]]ffhhijkottttt<<XYYbbddefgklllllllr   c                 b   t                      } t          |            t          |            t          |           }|                    ddddddd                                          }|                    d	ddddd|d
         dd                                          }|d         d |                    d                                          D             v sJ |                    dddddd                                          }|                    ddddd|d
         dd                                          }|d         d |                    d                                          D             v sJ |                     d                                          d         dk    sJ d S )Nz/api/accounts/previewzInline BankzInline Cashcashr\   zinline account)platform_nameaccount_nameaccount_typera   r3   r5   z/api/accounts/confirmr9   T)r   r   r   ra   r3   r9   r;   	entity_idc                    g | ]
}|d          S )r   r   r?   s     r   
<listcomp>zUtest_inline_account_and_wallet_creation_refresh_targets_and_audit.<locals>.<listcomp>   s    #n#n#n#C$5#n#n#nr   z/api/reference/accountsz/api/wallets/previewzInline WalletsoftwareMetaMaskzinline wallet)namewallet_typer   r3   z/api/wallets/confirm)r   r   r   r3   r9   r;   c                    g | ]
}|d          S )r-   r   r?   s     r   r   zUtest_inline_account_and_wallet_creation_refresh_targets_and_audit.<locals>.<listcomp>   s    "a"a"a3{#3"a"a"ar   z/api/walletszaSELECT COUNT(*) FROM audit_log WHERE action IN ('account_create_confirm','wallet_create_confirm')r      )	r   r	   r#   r   rD   r6   getr   rF   )r   rH   account_previewaccountwallet_previewwallets         r   Atest_inline_account_and_wallet_creation_refresh_targets_and_auditr      s   ::D'---uT{{{T]]Fkk"9R_q~  QW  ej  tD  AE  AEk  F  F  K  K  M  MOkk1-iv  IO  ]b  l|  L[  \h  Li  vz  9{  9{k  |  |  A  A  C  CG;#n#nLeAfAfAkAkAmAm#n#n#nnnnn[[!7gq  EO  Yh  ?i  ?i[  j  j  o  o  q  qN[[/_i  }G  Q`  p~  K  pL  Y]  7^  7^[  _  _  d  d  f  fF+"a"avzz.?Y?Y?^?^?`?`"a"a"aaaaa<<{||  F  F  H  H  IJ  K  OP  P  P  P  P  P  Pr   )r
   r   )r   r   r
   r   )r   r   r
   r   )r
   r   )
__future__r   collections.abcr   r   r   fastapi.testclientr   jarvis_finance.api.dependenciesr   jarvis_finance.api.mainr   !jarvis_finance.storage.migrationsr	   r   r   r#   rM   rV   rp   r   r   r   r   r   r   <module>r      s\   " " " " " " $ $ $ $ $ $        ) ) ) ) ) ) 2 2 2 2 2 2 . . . . . . > > > > > >         $t t t t:( ( ( (& & & &2t t t t&
m 
m 
m 
mP P P P P Pr   