
    Lrdj                        d dl mZ d dlZd dlmc mZ d dlm	Z	 d dl
mZ d dlmZ d dlmZmZmZ d dlmZmZmZ d dlmZmZmZ d d	lmZmZmZmZmZm Z m!Z! d d
l"m#Z# d dl$m%Z%m&Z& d Z'ddZ(ddZ)ddZ*ddZ+ddZ,dS )    )annotationsN)
TestClient)get_db)
create_app)confirm_create_budget_accountcreate_budget_account_previewlist_budget_accounts)confirm_create_categorycreate_category_previewlist_categories)get_budget_overviewget_category_summaryget_monthly_summary)confirm_budget_transaction"confirm_reverse_budget_transactionconfirm_transfer!create_budget_transaction_previewcreate_transfer_previewlist_budget_transactions"reverse_budget_transaction_preview)connect_memory)apply_migrationsget_schema_versionc                 @    t                      } t          |            | S N)r   r   conns    r/home/agent/.hermes/worktrees/FinanceManager-sprint7-postfinance-portfolio-source/tests/unit/test_budget_phase1.pydbr      s     DTK    returnNonec                 t   t                      } t          |            t          |           }d}||k    }|st          j        d|fd||f          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        |          dz  }dd|iz  }t          t          j
        |                    d x}x}}d	 |                     d
          D             }h d}|j        } ||          }|sdt          j        |          t          j        |          dt          j                    v st          j        |          rt          j        |          ndt          j        |          dz  }t          t          j
        |                    d x}x}}d |                     d          D             }|d         }|j        } |            }d}	||	k    }
|
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         }|j        } |            }d}	||	k    }
|
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         }|j        } |            }d}	||	k    }
|
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!}||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)   ==)z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} == %(py6)sr   r   )py0py1py3py6zassert %(py8)spy8c                    h | ]
}|d          S )name .0rows     r   	<setcomp>zdtest_budget_phase1_tables_seeds_and_text_decimal_columns_are_created_idempotently.<locals>.<setcomp>!   s    gggcc&kgggr    z1SELECT name FROM sqlite_master WHERE type='table'>   budget_tagsbudget_accountsbudget_transfersbudget_categoriesbudget_transactionsbudget_transaction_tagszJassert %(py6)s
{%(py6)s = %(py3)s
{%(py3)s = %(py1)s.issubset
}(%(py4)s)
}tables)r(   r)   py4r*   c                ,    i | ]}|d          |d         S )r-   typer.   r/   s     r   
<dictcomp>zetest_budget_phase1_tables_seeds_and_text_decimal_columns_are_created_idempotently.<locals>.<dictcomp>*   s"    jjjCs6{CKjjjr    z&PRAGMA table_info(budget_transactions)amount_originalTEXT)zD%(py5)s
{%(py5)s = %(py3)s
{%(py3)s = %(py1)s.upper
}()
} == %(py8)s)r(   r)   py5r+   zassert %(py10)spy10fx_rate_to_chf
amount_chfz&SELECT COUNT(*) FROM budget_categoriesr      z%(py1)s == %(py4)sr(   r:   assert %(py6)sr*   z SELECT COUNT(*) FROM budget_tags
   )r   r   r   
@pytest_ar_call_reprcompare@py_builtinslocals_should_repr_global_name	_safereprAssertionError_format_explanationexecuteissubsetupperfetchone)r   @py_assert2@py_assert5@py_assert4@py_format7@py_format9r9   @py_assert0tx_cols@py_assert7@py_assert6@py_format11@py_assert3@py_format5s                 r   Qtest_budget_phase1_tables_seeds_and_text_decimal_columns_are_created_idempotentlyra      s$   44DTd##)r)#r))))))))))#r))))))))))))))))))))))))))))))d)))))d))))))#))))r)))))))))))))))))))))))))))ggT\\2e%f%fgggF                            v    v                          kj4<<@h3i3ijjjG$%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7777777777#$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66666666666666< 2 &2&&((2F2(F2222222222(F22222 2222&2222(2222F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222<<@AAJJLLQOUSUUOSUUUUUUUUUUUOSUUUUUUOUUUUSU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<<:;;DDFFqIOROIROOOOOOOOOOIROOOOOIOOOOROOOOOOOOOOOOOOOOOOOOOOOOOOOOOr    c                    t                      } t          | 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}}t          | |d                   }|d         }|d         }|s:ddt          j        |          iz  }	t          t          j        |	                    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}}t          ddg          
                    | |          }
|
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|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 S )Nz
Demo KontocheckingCHFr-   account_typecurrencysummaryu   Demo Konto · checking · CHFr%   rE   rF   rG   r*   payload	entity_idaudit_idassert %(py1)sr(   r   r-   z'jarvis_finance.services.budget_accountsarchive_budget_accountfromliststatusarchivedz?SELECT is_active FROM budget_accounts WHERE budget_account_id=?)r   r   rI   rJ   rN   rO   rP   r   r	   
__import__rm   rQ   rT   )r   previewrZ   r_   rU   r`   rX   	confirmed
account_id@py_format2rq   s              r   5test_budget_accounts_preview_confirm_archive_and_listrw   2   s   44D+D<Ycqv2w2wxxG9@!@@!@@@@@@@@@@@!@@@@@@@@@@!@@@@@@@@@@@@@@@@@@@@@@@@@@@@-dGI4FGGI;'JZ                         %%a(0@L@0L@@@@@@@@@@0L@@@@@0@@@@L@@@@@@@@@@@@@@@@@@@@@@@@@@@COgNhiii  A  A  BF  HR  S  SHH++++++++++++++++++++++++++++++++++++++++++++++++<<Y\f[hiirrttuvw|{||w{|||||||||||w{||||||w||||{||||||||||||||||||||||||||||||r    c            	        t                      } t          |           }t          d |D                       }t          | dd|d         d          }t	          | |d                   }|d         }fdt          |           }d} ||          }|s$d	d
t          j                    v st          j                  rt          j	                  nd
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  }	t          t          j        |	                    d x}x}}t          ddg                              | |          }
|
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 )Nc              3  2   K   | ]}|d          dk    |V  dS r-   zEssen & HaushaltNr.   r0   cs     r   	<genexpr>zAtest_budget_categories_tree_create_and_archive.<locals>.<genexpr>C   s1      KK1V98J+J+J!+J+J+J+JKKr    Drogerieexpensecategory_id)r-   category_typeparent_category_idri   rj   c                >    t          fd| D                       S )Nc              3  p   K   | ]0}|d          k    p |                     dg                     V  1dS )r-   childrenN)get)r0   itemcontainsr-   s     r   r}   zStest_budget_categories_tree_create_and_archive.<locals>.contains.<locals>.<genexpr>H   sL      ffX\4<4'S88DHHZ4L4Ld+S+Sffffffr    )any)itemsr-   r   s    `r   r   z@test_budget_categories_tree_create_and_archive.<locals>.containsG   s+    fffff`effffffr    zSassert %(py8)s
{%(py8)s = %(py0)s(%(py4)s
{%(py4)s = %(py1)s(%(py2)s)
}, %(py6)s)
}r   r   r   )r'   r(   py2r:   r*   r+   z)jarvis_finance.services.budget_categoriesarchive_categoryrn   rp   rq   r%   rE   rF   rG   r*   )r   r   nextr   r
   rK   rL   rI   rM   rN   rO   rP   rr   r   rJ   )r   
categoriesparentrs   rt   r   r_   rV   r\   rY   rq   rZ   rU   r`   rX   r   s                  @r   .test_budget_categories_tree_create_and_archiver   @   s   44D &&JKKZKKKKKF%dZR[sy  {H  tI  -J  -J  K  KG'gi.@AAIK(Kg g g g g $D))6:688):66666666666666686666686666666666666O66666O6666666666666D66666D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EQcPdeeevvw{  ~I  J  JHH++++++++++++++++++++++++++++++++++++++++++++++++++r    c            
        t                      } t          | dddd          d         }t          | dddd          d         }t          d t          |           D                       d	         }|d
dddd|dgd}t	          | |          }|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}}t          | |d                   }|d         }|d         }|s:ddt          j        |          iz  }t          t          j	        |                    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}}t	          | i |ddd d 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}}t	          | i |d$d%d&          }|d         }d'd(h}||v }|slt          j        d)|fd*||f          t          j        |          t          j        |          dz  }	dd|	iz  }
t          t          j	        |
                    d x}x}}t          | ||d+ddd,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}}t          | |d.d/i          }|d0         }|j        }d1} ||          }|ssd2t          j        |          t          j        |          t          j        |          t          j        |          d3z  }t          t          j	        |                    d x}x}x}}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}}|                     d4                                          d         }d5}||k    }|slt          j        d6|fd7||f          t          j        |          t          j        |          dz  }	dd|	iz  }
t          t          j	        |
                    d x}x}}t%          |           }t'          |          }d8}||k    }|sMt          j        d6|fd9||f          d:t)          j                    v st          j        t&                    rt          j        t&                    nd: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}}t/          |           d@         }|s:ddt          j        |          iz  }t          t          j	        |                    d }t1          | dA          dB         }dA}||k    }|slt          j        d|fd||f          t          j        |          t          j        |          dz  }	dd|	iz  }
t          t          j	        |
                    d x}x}}dA}t3          | |          }|sdCdDt)          j                    v st          j        t2                    rt          j        t2                    ndDd<t)          j                    v st          j        |           rt          j        |           nd<t          j        |          t          j        |          dEz  }t          t          j	        |                    d x}}d S )FNHaushaltrc   rd   re   rj   Reservesavingsc              3  2   K   | ]}|d          dk    |V  dS rz   r.   r{   s     r   r}   zXtest_manual_income_expense_transfer_reversal_and_overview_write_audit.<locals>.<genexpr>S   s1      XX!&	EW8W8WA8W8W8W8WXXr    r   r   
2026-05-16zSynthetische Ausgabez12.34Einmalig)ru   transaction_typetransaction_datedescriptionr>   currency_originalr   	tag_names	fx_status
not_neededr%   rE   rF   rG   r*   ri   rk   rl   r(   zUSELECT typeof(amount_original) FROM budget_transactions WHERE budget_transaction_id=?r   textincomezSynthetische Einnahmez20.00)r   r   r>   r   rp   rt   EURz5.00)r   r>   missingok)in)z%(py1)s in %(py4)sz3.00zSynthetischer Transfer)from_account_idto_account_idr>   r   r   r   reasonzSynthetische Korrekturrh   ReversalzLassert %(py7)s
{%(py7)s = %(py3)s
{%(py3)s = %(py1)s.startswith
}(%(py5)s)
})r(   r)   r@   py7z@SELECT COUNT(*) FROM audit_log WHERE entity_type LIKE 'budget_%'   )>=)z%(py1)s >= %(py4)s   )zN%(py6)s
{%(py6)s = %(py0)s(%(py4)s
{%(py4)s = %(py1)s(%(py2)s)
})
} >= %(py9)slenr   r   )r'   r(   r   r:   r*   py9zassert %(py11)spy11current_monthz2026-05monthz5assert %(py5)s
{%(py5)s = %(py0)s(%(py1)s, %(py3)s)
}r   )r'   r(   r)   r@   )r   r   r   r   r   rI   rJ   rN   rO   rP   r   rQ   rT   r   r   r   
startswithr   r   r   rK   rL   rM   r   r   r   )r   	account_a	account_bcategoryexpense_payloadrs   rZ   r_   rU   r`   rX   rt   tx_idrv   income_preview
fx_previewtransfer_previewtransferrev_previewrW   r]   @py_format8reversalrV   @py_assert8r\   @py_format10@py_format12@py_format6s                                r   Etest_manual_income_expense_transfer_reversal_and_overview_write_auditr   O   s   44D-dZYcqv4w4wxx  zE  FI-dYXaot4u4uvv  xC  DIXXt44XXXXXYfgH  %(-"" \	 	O 0oFFG;/</<//////////</////////<///////////////////////////*41CDDIk"EZ                         <<orwqyzz  D  D  F  F  GH  I  S  MS  S  I  MS  S  S  S  S  S  S  S  S  S  S  I  MS  S  S  S  S  S  I  S  S  S  S  M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  S6t  >H  >Hem  V  kr  CG  >H  >H  >H  I  IN%dN9,EFFxP_T__PT___________PT______P____T____________________________24  :DO  :Dbg  }C  :D  :D  :D  E  EJk"7y$&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.ten  DJ  af  |H  Yq  6r  6r  s  s&6y&ABBHH,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,4T58MeBfggKy!8!,8Z8,,Z88888888!8888,8888Z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1${9?UVVHH,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,<<Z[[ddffghinmnnimnnnnnnnnnnnimnnnnnninnnnmnnnnnnnnnnnnnnnnnnnnnnnnnnnn'--33-..3!3.!3333333333.!3333333333333333333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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t$$_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tY//8EIE8IEEEEEEEEEE8IEEEEE8EEEEI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&/0i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000i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            	     p   t                      t                      } fd}|| j        t          <   t	          |           }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}}|                    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}}|
                                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}}|                    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}}|j        }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        |          t          j        |          t          j        |          t          j        |          dz  }d d!|iz  }t          t          j        |                    d x}x}x}x}x}}|j        }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        |          t          j        |          t          j        |          t          j        |          dz  }d d!|iz  }t          t          j        |                    d x}x}x}x}x}}|j        }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        |          t          j        |          t          j        |          t          j        |          dz  }d d!|iz  }t          t          j        |                    d x}x}x}x}x}}d S )$Nc               3     K    V  d S r   r.   r   s   r   override_dbzKtest_budget_api_endpoints_preview_confirm_and_overview.<locals>.override_db   s      




r    z	API Kontorc   rd   re   z/api/budget/accounts/preview)json   r%   )z3%(py2)s
{%(py2)s = %(py0)s.status_code
} == %(py5)srs   )r'   r   r@   zassert %(py7)sr   z/api/budget/accounts/confirmri   confirmrj   r   r   zAPI Ausgabez10.00)ru   r   r   r   r>   r   z /api/budget/transactions/preview
tx_previewz /api/budget/transactions/confirm
tx_confirmz/api/budget/overview)zk%(py8)s
{%(py8)s = %(py6)s
{%(py6)s = %(py2)s
{%(py2)s = %(py0)s.get
}(%(py4)s)
}.status_code
} == %(py11)sclient)r'   r   r:   r*   r+   r   zassert %(py13)spy13z/api/budget/transactionsz,/api/budget/categories/summary?month=2026-05)r   r   dependency_overridesr   r   poststatus_coderI   rJ   rK   rL   rM   rN   rO   rP   r   r   )appr   r   account_payloadrs   @py_assert1rW   r_   r   r   r   ru   
tx_payloadr   r   rV   r\   @py_assert10@py_assert9r   @py_format14r   s                        @r   6test_budget_api_endpoints_preview_confirm_and_overviewr   {   sO   44D
,,C     (3CV$__F*JTYZZOkk8kOOG%#%#%%%%%%%%%%#%%%%%%%%%%%%7%%%%%7%%%%%%%%%%#%%%%%%%%%%%%%%%%%%%%%%%%%%%kk8w||~~i?XkYYG%#%#%%%%%%%%%%#%%%%%%%%%%%%7%%%%%7%%%%%%%%%%#%%%%%%%%%%%%%%%%%%%%%%%%%%%,J *	_k  }J  _f  }B  C  CJ?jQQJ!(S(!S((((((((((!S((((((((((((:(((((:((((((!((((S(((((((((((((((((((((((((((?jooFWFWXaFbccJ!(S(!S((((((((((!S((((((((((((:(((((:((((((!((((S(((((((((((((((((((((((((((:@,@::,--@-9@S@9S@@@@@@@@@@9S@@@@@@@@@@@@6@@@@@6@@@@@@:@@@@,@@@@-@@@@9@@@@S@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@:D0D::011D1=DD=DDDDDDDDDD=DDDDDDDDDDDD6DDDDD6DDDDDD:DDDD0DDDD1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:XDX::DEEXEQXUXXQUXXXXXXXXXXXQUXXXXXXXXXXXXX6XXXXX6XXXXXX:XXXXDXXXXEXXXXQXXXXUXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXr    )r!   r"   )-
__future__r   builtinsrK   _pytest.assertion.rewrite	assertionrewriterI   fastapi.testclientr   jarvis_finance.api.dependenciesr   jarvis_finance.api.mainr   'jarvis_finance.services.budget_accountsr   r   r	   )jarvis_finance.services.budget_categoriesr
   r   r   'jarvis_finance.services.budget_overviewr   r   r   +jarvis_finance.services.budget_transactionsr   r   r   r   r   r   r   jarvis_finance.storage.databaser   !jarvis_finance.storage.migrationsr   r   r   ra   rw   r   r   r   r.   r    r   <module>r      s   " " " " " "               ) ) ) ) ) ) 2 2 2 2 2 2 . . . . . . G  G  G  G  G  G  G  G  G  G w w w w w w w w w w r r r r r r r r r r                  ; : : : : : R R R R R R R R  P P P P*} } } }, , , ,)1 )1 )1 )1XY Y Y Y Y Yr    