
    mj.1                        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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    *tests/unit/test_fastapi_vue_cockpit_v11.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 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', '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 market_prices(market_price_id, instrument_id, price_date, close, currency, provider, quality_status, created_at) VALUES ('mp1', 'inst1', '2026-05-15', '10.50', 'CHF', 'local', 'ok', ?)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_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', ?)zINSERT INTO crypto_prices(crypto_price_id, asset_id, coingecko_id, price_currency, price, provider, provider_timestamp, fetched_at, quality_status) VALUES ('cp1', 'btc', 'bitcoin', 'CHF', '80000', 'local', ?, ?, 'fresh'))r   commit)r   nows     r   _seedr$      s   
 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  X  [^  Z`  a  a  aLL  N  QT  PV  W  W  WLL  K  NQ  MS  T  T  TLL  S  VY  U[  \  \  \LL  n  qt  pv  w  w  wLL  p  sv  x{  r|  }  }  }KKMMMMMr   c                    t                      } t          |            t          |            t          |                               dddd                                          }|d         d         dk    sJ |d         d	         d
k    sJ |d         d         dk    sJ dt          |                                          vsJ dt          |                                          vsJ d S )Nz/api/instruments/searchstockdemo)asset_classqueryjsonr   labelzDemo EquityisinCH0000000000providerlocalapi_keysecret)r   r	   r$   r   postr+   strlower)r   payloads     r   :test_instrument_search_is_local_sanitized_and_decimal_freer7   /   s    ::D'---uT{{{dmm  !:QXciAjAj kkpprrG1:g-////1:f////1:j!W,,,,CLL..0000003w<<--////////r   c                    t                      } t          |            t          |            t          |           }ddddddd}|                    d|	                                          }|d
         g k    sJ |d         dk    sJ |                     d                                          d         dk    sJ |                    di ||d         dd	                                          }|d         dk    sJ t          |d         t                    sJ |                     d                                          d         dk    sJ |                     d                                          d         dk    sJ d S )Ncash1CHFz250.25cash_deposit
2026-05-17zmanual deposit
account_idcurrencyamounttransaction_typebooking_datenote/api/cash/previewr*   warnings
amount_chfzSELECT COUNT(*) FROM audit_logr   /api/cash/confirm
preview_idTrH   confirmstatus	confirmedaudit_idzFSELECT COUNT(*) FROM cash_balances WHERE source_type='vue_manual_cash'   :SELECT COUNT(*) FROM audit_log WHERE action='cash_confirm')
r   r	   r$   r   r3   r+   r   fetchone
isinstancer4   r   clientrequestpreviewrL   s        r   Ftest_cash_preview_confirm_writes_snapshot_and_audit_only_after_confirmrV   :   s   ::D'---uT{{{T]]F$%8ao  BN  Xh  i  iGkk-Gk<<AACCG:"$$$$< H,,,,<<899BBDDQG1LLLL/6w6wPWXdPerv6w6w6wxx}}IX+----i
+S11111<<`aajjllmnosttttt<<TUU^^``abcghhhhhhhr   c            
        t                      } t          |            t          |            t          |           }ddddddddd	d
	}|                    d|                                          }|d         dk    sJ |d         dk    sJ |d         g k    sJ |                    di ||d         dd                                          }|d         dk    sJ |                     d                                          d         dk    sJ |                     d                                          d         dk    sJ d S )Nr&   broker1inst13r:   r<   initial_snapshot30zopening snapshot)	r(   r>   instrument_idquantityr?   
trade_daterA   cost_basis_originalrC   z/api/positions/previewr*   r(   	fx_status
not_neededrE   z/api/positions/confirmrH   TrI   rK   rL   zISELECT COUNT(*) FROM transactions WHERE source_type='vue_manual_position'r   rN   z>SELECT COUNT(*) FROM audit_log WHERE action='position_confirm'r   r	   r$   r   r3   r+   r   rP   rR   s        r   Atest_equity_position_preview_confirm_writes_transaction_and_auditrd   L   s   ::D'---uT{{{T]]F%YQXfiw|  MY  oA  Z^  hz  {  {Gkk2kAAFFHHG=!W,,,,;<////:"$$$$4;|g;|U\]iUjw{;|;|;|}}  C  C  E  EIX+----<<cddmmoopqrvwwwww<<XYYbbddefgklllllllr   c                 H   t                      } t          |            t          |            t          |           }|                    d                                          }|                    d                                          }|                    d                                          }|                    d                                          }|                    d                                          }|d         ddd d	gk    sJ |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 t          |||||g                                          }d|vrd|vrd|vsJ d S )Nz&/api/portfolio/positions/broker1:inst1/api/crypto/positions/btcz/api/cash/positions/cash1:CHFz /api/market/prices/inst1/historyz/api/crypto/prices/btc/historyavailable_actionsVerlaufT)r,   enabledreasonr   r,   
Einzahlungu   Live-Modus spätervaluez10.5080000r1   tokenr2   )r   r	   r$   r   getr+   r4   r5   )r   rS   equitycryptocashmarket_historycrypto_historyrendereds           r   6test_details_audit_and_history_endpoints_are_user_saferw   ]   s   ::D'---uT{{{T]]FZZ@AAFFHHFZZ34499;;F::566;;==DZZ BCCHHJJNZZ @AAFFHHN%&Y4[_+`+`*aaaaa#$Q'0L@@@@%&r*737KKKKK!W%0000!W%0000FFD..IJJPPRRHH$$)@)@XU]E]E]E]]E]E]r   c                    t                      } t          |            t          |            d}|                     d|f           |                     d           |                     d|f           |                     d           |                                  t          |                               d                                          }d |d         D             }t          |          d	d
gk    sJ |d	         d         dk    sJ |d
         d         dk    sJ |d	         d         dk    sJ t          d |d         D                       t          |d                   k    sJ d S )Nr!   z{INSERT INTO crypto_wallets(wallet_id, wallet_name, wallet_type, created_at) VALUES ('w2', 'Exchange Wallet', 'exchange', ?)zGUPDATE crypto_holdings SET quantity='0.30' WHERE crypto_holding_id='h1'zINSERT INTO crypto_holdings(crypto_holding_id, wallet_id, asset_id, quantity, verification_status, created_at) VALUES ('h2', 'w2', 'btc', '0.20', 'ok', ?)	  INSERT INTO crypto_prices(crypto_price_id, asset_id, coingecko_id, price_currency, price, provider, provider_timestamp, fetched_at, quality_status) VALUES ('cp_old', 'btc', 'bitcoin', 'CHF', '70000', 'local', '2026-05-15T12:00:00Z', '2026-05-15T12:00:00Z', 'stale')rf   c                     i | ]}|d          |S )walletr   .0rows     r   
<dictcomp>z]test_crypto_detail_aggregates_wallet_holdings_before_joining_latest_price.<locals>.<dictcomp>{   s    LLLXLLLr   wallet_allocationszCold WalletzExchange Walletr^   z0.30z0.20market_value_chfz24000.00c              3  @   K   | ]}t          |d                    V  dS )r^   N)floatr|   s     r   	<genexpr>z\test_crypto_detail_aggregates_wallet_holdings_before_joining_latest_price.<locals>.<genexpr>   s.      NN#uS_%%NNNNNNr   quantity_total)r   r	   r$   r   r"   r   rp   r+   listsumr   )r   r#   detail	by_wallets       r   Itest_crypto_detail_aggregates_wallet_holdings_before_joining_latest_pricer   p   s   ::D'---uT{{{
 CLL  O  RU  QW  X  X  XLLZ[[[LL  n  qt  pv  w  w  wLL  ]  ^  ^  ^KKMMMT]]:;;@@BBFLLv6J/KLLLI	??}.?@@@@@]#J/69999&'
3v====]#$67:EEEENN8L1MNNNNNRWX^_oXpRqRqqqqqqqr   c                    t                      } t          |            t          |            |                     d           |                                  t          |           }|                    d                                          }|                    d                                          }|d         d         dk    sJ d |d         D             d	gk    sJ |d         d         d         dk    sJ d S )
Nry   z/api/walletsz/api/wallets/w1r   r   z20000.00c                    g | ]
}|d          S )asset_idr   )r}   coins     r   
<listcomp>zbtest_wallet_summaries_and_details_use_latest_price_without_duplicate_coin_rows.<locals>.<listcomp>   s    999D999r   coinsbtc)r   r	   r$   r   r"   r   rp   r+   )r   rS   walletsr   s       r   Ntest_wallet_summaries_and_details_use_latest_price_without_duplicate_coin_rowsr      s    ::D'---uT{{{LL  ]  ^  ^  ^KKMMMT]]Fjj((--//GZZ)**//11F1:()Z777799999eWDDDD'?101Z??????r   c                    t                      } t          |            t          |            t          |           }ddddddd}|                    d|	                                          }|d
                             d          sJ |d         g k    sJ |                     d                                          d         dk    sJ |                    di ||d         dd	                                          }|d         dk    sJ |                     d                                          d         dk    sJ |                     d                                          d         dk    sJ d S )Nr   w1z
0.12500001increaser<   zmanual top-upr   	wallet_idr^   rA   effective_daterC   /api/crypto/actions/previewr*   summaryu   Crypto Bestand erhöhenrE   z(SELECT COUNT(*) FROM crypto_transactionsr   /api/crypto/actions/confirmrH   TrI   rK   rL   zHSELECT quantity FROM crypto_transactions WHERE source='manual_dashboard'FSELECT COUNT(*) FROM audit_log WHERE action='crypto_manual_adjustment'rN   	r   r	   r$   r   r3   r+   
startswithr   rP   rR   s        r   Jtest_crypto_manual_adjustment_preview_confirm_writes_transaction_and_auditr      s   ::D'---uT{{{T]]F tcm  BN  Xg  h  hGkk7gkFFKKMMG9(()BCCCCC:"$$$$<<BCCLLNNqQUVVVVV9  AB7  ABZabnZo  }A  AB  AB  AB  C  C  H  H  J  JIX+----<<bccllnnopq  vB  B  B  B  B<<`aajjllmnostttttttr   c                    t                      } t          |            t          |            t          |           }ddddddd}|                    d|	                                          }|d
                             d          sJ |                    di ||d         dd	                                          }|d         dk    sJ |                     d                                          d         dk    sJ d S )Nr   r   0set_zeror<   zclose manual test holdingr   r   r*   r   zCrypto auf 0 setzenr   rH   TrI   rK   rL   r   r   rN   r   rR   s        r   @test_crypto_set_zero_allows_zero_preview_and_confirms_adjustmentr      sJ   ::D'---uT{{{T]]F tZd  yE  Oj  k  kGkk7gkFFKKMMG9(()>?????9  AB7  ABZabnZo  }A  AB  AB  AB  C  C  H  H  J  JIX+----<<`aajjllmnostttttttr   c                    t                      } t          |            t          |            t          |           }ddddddd}dddd	dd
d}|                    d|                                          }|d         dk    sJ |                    di ||d         dd                                          }|d         dk    sJ |                     d                                          d d          dk    sJ |                    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 )Nr9   r:   25.00
Auszahlungr<   zcash outr=   z5.00	Korrekturzmanual correctionrD   r*   r   zAuszahlung CHF 25.00rG   rH   TrI   rK   rL   zWSELECT transaction_type, gross_amount_original FROM transactions WHERE notes='cash out')cash_withdrawalr   zISELECT transaction_type FROM transactions WHERE notes='manual correction'r   manual_cash_correctionrO      rc   )r   rS   
withdrawal
correction	w_preview	w_confirm	c_preview	c_confirms           r   Qtest_cash_withdrawal_and_correction_preview_confirm_use_positive_amount_and_auditr      sU   ::D'---uT{{{T]]F 'Ugco  BN  Xb  c  cJ 'Ufbm  @L  Vi  j  jJ/jAAFFHHIY#99999/6|6|S\]iSjw{6|6|6|}}  C  C  E  EIX+----<<qrr{{}}~~~  A  Ea  a  a  a  a/jAAFFHHI/6|6|S\]iSjw{6|6|6|}}  C  C  E  EIX+----<<cddmmoopqr  wO  O  O  O  O<<TUU^^``abcghhhhhhhr   c                 F   ddl m}  dd l} | t                                                    j        d         }dD ]f}||z  }|                                sJ |                                j        |j        z  sJ |	                                }d|vsJ d|vsJ d|vsJ gd S )Nr   )Pathr   )zscripts/start_vue_dashboard.shzscripts/stop_vue_dashboard.shAPI_KEYTOKENSECRET)
pathlibr   stat__file__resolveparentsexistsst_modeS_IXUSR	read_text)r   r   reporelscripttexts         r   Mtest_vue_dashboard_scripts_exist_are_executable_and_do_not_print_secret_namesr      s    KKK4>>!!##+A.DR $ $}}{{}}$t|3333!!$$$$d""""t#####$ $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$   r7   rV   rd   rw   r   r   r   r   r   r   r   r   r   <module>r      s   " " " " " " $ $ $ $ $ $        ) ) ) ) ) ) 2 2 2 2 2 2 . . . . . . > > > > > >          0 0 0 0i i i i$m m m m"^ ^ ^ ^&r r r r&@ @ @ @u u u u"
u 
u 
u 
ui i i i&$ $ $ $ $ $r   