
    ܴ
j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y)    )annotations)IteratorN)
Connection)
TestClient)get_db)
create_app)apply_migrationsc                     t        j                  dd      } t         j                  | _        | 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      s0    ??:?D{{DLL+,K    c                `     t               }d fd}||j                  t        <   t        |      S )Nc               3     K     y w)N r   s   r   override_dbz_client.<locals>.override_db   s     
s   	)returnzIterator[Connection])r   dependency_overridesr   r   )r   appr   s   `  r   _clientr      s+    
,C (3CV$c?r   c                   d}| j                  d|f       | j                  d|f       | j                  d|f       | j                  d|f       | j                  d|f       | j                  d|f       | j                  d|f       | j                  d	|f       | j                  d
|f       | j                  d|f       | j                  d||f       | j                          y )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LL  i  lo  kq  rLL  k  nq  ms  tLL  l  or  nt  uLL  |  B  ~D  ELL  X  [^  Z`  aLL  N  QT  PV  WLL  K  NQ  MS  TLL  S  VY  U[  \LL  n  qt  pv  wLL  p  sv  x{  r|  }KKMr   c                 `   t               } t        |        t        |        t        |       j	                  dddd      j                         }|d   d   dk(  sJ |d   d	   d
k(  sJ |d   d   dk(  sJ dt        |      j                         vsJ dt        |      j                         vsJ y )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_freer5   /   s    :D'-uT{dm  !:QXciAj kpprG1:g-///1:f///1:j!W,,,CL..00003w<--////r   c                 T   t               } t        |        t        |        t        |       }ddddddd}|j	                  d|	      j                         }|d
   g k(  sJ |d   dk(  sJ | j                  d      j                         d   dk(  sJ |j	                  di ||d   dd	      j                         }|d   dk(  sJ t        |d   t              sJ | j                  d      j                         d   dk(  sJ | j                  d      j                         d   dk(  sJ y )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rF   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   r1   r)   r   fetchone
isinstancer2   r   clientrequestpreviewrJ   s        r   Ftest_cash_preview_confirm_writes_snapshot_and_audit_only_after_confirmrT   :   sQ   :D'-uT{T]F$%8ao  BN  Xh  iGkk-Gk<AACG:"$$$< H,,,<<89BBDQG1LLL/6w6wPWXdPerv6wx}}IX+---i
+S111<<`ajjlmnostttt<<TU^^`abcghhhhr   c            
        t               } t        |        t        |        t        |       }ddddddddd	d
	}|j	                  d|      j                         }|d   dk(  sJ |d   dk(  sJ |d   g k(  sJ |j	                  di ||d   dd      j                         }|d   dk(  sJ | j                  d      j                         d   dk(  sJ | j                  d      j                         d   dk(  sJ y )Nr$   broker1inst13r8   r:   initial_snapshot30zopening snapshot)	r&   r<   instrument_idquantityr=   
trade_dater?   cost_basis_originalrA   z/api/positions/previewr(   r&   	fx_status
not_neededrC   z/api/positions/confirmrF   TrG   rI   rJ   zISELECT COUNT(*) FROM transactions WHERE source_type='vue_manual_position'r   rL   z>SELECT COUNT(*) FROM audit_log WHERE action='position_confirm'r   r	   r"   r   r1   r)   r   rN   rP   s        r   Atest_equity_position_preview_confirm_writes_transaction_and_auditrb   L   sD   :D'-uT{T]F%YQXfiw|  MY  oA  Z^  hz  {Gkk2kAFFHG=!W,,,;<///:"$$$4;|g;|U\]iUjw{;|}  C  C  EIX+---<<cdmmopqrvwwww<<XYbbdefgkllllr   c                 |   t               } t        |        t        |        t        |       }|j	                  d      j                         }|j	                  d      j                         }|j	                  d      j                         }|j	                  d      j                         }|j	                  d      j                         }|d   d   d   d	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      j                         }d|vrd|vrd|vsJ y )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_actionsr   r*   Kaufen
Einzahlungu   Live-Modus spätervaluez10.5080000r/   tokenr0   )r   r	   r"   r   getr)   r2   r3   )r   rQ   equitycryptocashmarket_historycrypto_historyrendereds           r   6test_details_audit_and_history_endpoints_are_user_safers   ]   sa   :D'-uT{T]FZZ@AFFHFZZ3499;F::56;;=DZZ BCHHJNZZ @AFFHN%&q)'2h>>>#$Q'0L@@@%&r*737KKKK!W%000!W%000FFD..IJPPRHH$)@XU]E]]]E]r   c                 <   t               } t        |        t        |        d}| j                  d|f       | j                  d       | j                  d|f       | j                  d       | j	                          t        |       j                  d      j                         }|d   D ci c]  }|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 y c c}w )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')rd   wallet_allocationswalletzCold WalletzExchange Walletr\   z0.30z0.20market_value_chfz24000.00c              3  8   K   | ]  }t        |d            yw)r\   N)float).0rows     r   	<genexpr>z\test_crypto_detail_aggregates_wallet_holdings_before_joining_latest_price.<locals>.<genexpr>   s     N#uS_%Ns   quantity_total)r   r	   r"   r   r    r   rl   r)   listsumrz   )r   r!   detailr|   	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LLZ[LL  n  qt  pv  wLL  ]  ^KKMT]:;@@BF/56J/KLX#LIL	?}.?@@@@]#J/6999&'
3v===]#$67:EEEN8L1MNNRWX^_oXpRqqqq Ms   *Dc                    t               } t        |        t        |        | j                  d       | j	                          t        |       }|j                  d      j                         }|j                  d      j                         }|d   d   dk(  sJ |d   D cg c]  }|d   	 c}d	gk(  sJ |d   d   d   dk(  sJ y c c}w )
Nru   z/api/walletsz/api/wallets/w1r   rx   z20000.00coinsasset_idbtc)r   r	   r"   r   r    r   rl   r)   )r   rQ   walletsr   coins        r   Ntest_wallet_summaries_and_details_use_latest_price_without_duplicate_coin_rowsr      s    :D'-uT{LL  ]  ^KKMT]Fjj(--/GZZ)*//1F1:()Z777)/9D9eWDDD'?101Z??? :s   Cc                 B   t               } t        |        t        |        t        |       }ddddddd}|j	                  d|	      j                         }|d
   j                  d      sJ |d   g k(  sJ | j                  d      j                         d   dk(  sJ |j	                  di ||d   dd	      j                         }|d   dk(  sJ | j                  d      j                         d   dk(  sJ | j                  d      j                         d   dk(  sJ y )Nr   w1z
0.12500001increaser:   zmanual top-upr   	wallet_idr\   r?   effective_daterA   /api/crypto/actions/previewr(   summaryu   Crypto Bestand erhöhenrC   z(SELECT COUNT(*) FROM crypto_transactionsr   /api/crypto/actions/confirmrF   TrG   rI   rJ   zHSELECT quantity FROM crypto_transactions WHERE source='manual_dashboard'FSELECT COUNT(*) FROM audit_log WHERE action='crypto_manual_adjustment'rL   	r   r	   r"   r   r1   r)   
startswithr   rN   rP   s        r   Jtest_crypto_manual_adjustment_preview_confirm_writes_transaction_and_auditr      sm   :D'-uT{T]F tcm  BN  Xg  hGkk7gkFKKMG9(()BCCC:"$$$<<BCLLNqQUVVVV9  AB7  ABZabnZo  }A  AB  C  H  H  JIX+---<<bcllnopq  vB  B  B  B<<`ajjlmnosttttr   c                    t               } t        |        t        |        t        |       }ddddddd}|j	                  d|	      j                         }|d
   j                  d      sJ |j	                  di ||d   dd	      j                         }|d   dk(  sJ | j                  d      j                         d   dk(  sJ y )Nr   r   0set_zeror:   zclose manual test holdingr   r   r(   r   zCrypto auf 0 setzenr   rF   TrG   rI   rJ   r   r   rL   r   rP   s        r   @test_crypto_set_zero_allows_zero_preview_and_confirms_adjustmentr      s    :D'-uT{T]F tZd  yE  Oj  kGkk7gkFKKMG9(()>???9  AB7  ABZabnZo  }A  AB  C  H  H  JIX+---<<`ajjlmnosttttr   c                    t               } t        |        t        |        t        |       }ddddddd}dddd	dd
d}|j	                  d|      j                         }|d   dk(  sJ |j	                  di ||d   dd      j                         }|d   dk(  sJ | j                  d      j                         d d  dk(  sJ |j	                  d|      j                         }|j	                  di ||d   dd      j                         }|d   dk(  sJ | j                  d      j                         d   dk(  sJ | j                  d      j                         d   dk\  sJ y )Nr7   r8   25.00
Auszahlungr:   zcash outr;   z5.00	Korrekturzmanual correctionrB   r(   r   zAuszahlung CHF 25.00rE   rF   TrG   rI   rJ   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_correctionrM      ra   )r   rQ   
withdrawal
correction	w_preview	w_confirm	c_preview	c_confirms           r   Qtest_cash_withdrawal_and_correction_preview_confirm_use_positive_amount_and_auditr      s   :D'-uT{T]F 'Ugco  BN  Xb  cJ 'Ufbm  @L  Vi  jJ/jAFFHIY#9999/6|6|S\]iSjw{6|}  C  C  EIX+---<<qr{{}~  A  Ea  a  a  a/jAFFHI/6|6|S\]iSjw{6|}  C  C  EIX+---<<cdmmopqr  wO  O  O  O<<TU^^`abcghhhhr   c                 8   ddl m}  dd l} | t              j	                         j
                  d   }dD ]d  }||z  }|j                         sJ |j                         j                  |j                  z  sJ |j                         }d|vsJ d|vsJ d|vrdJ  y )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    >!!#++A.DR $}}{{}$$t||333!$$$d"""t###$r   )r   r   )r   r   r   r   )r   r   r   None)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"   r5   rT   rb   rs   r   r   r   r   r   r   r   r   r   <module>r      sf    " $   ) 2 . > 0i$m"^&r&@u"
ui&$r   