
    ,j                         d 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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 Zd Zd Z G d d      Z G d d      Z G d d      Z G d d      Z G d d      Zy)u,   Historical budget vs. actuals — Story 4.5.    N)Decimal)date)db)Budget)Category)Account)Transactionc                     t        | dd      }t        j                  j                  |       t        j                  j	                          |S )NT)name	is_system	is_active)r   _dbsessionaddcommit)r   cats     F/var/www/html/financials/tests/test_blueprints/test_budgets_history.py_make_categoryr      s5    

=CKKOOCKKJ    c           
          t        | j                  ||t        t        |                  }t        j
                  j                  |       t        j
                  j                          |S )N)category_idyearmonthamount)r   idr   strr   r   r   r   )r   r   r   r   bs        r   _make_budgetr      sD    366E'#f+BVWAKKOOAKKHr   c                      t        ddd      } t        j                  j                  |        t        j                  j	                          | S )NCheckingcheckingT)r   typer   )r   r   r   r   r   )accts    r   _make_accountr$      s5    
tDDKKOODKKKr   c           	          t        | d|dddt        t        |            d| j                  |j                        }t        j
                  j                  |       t        j
                  j                          |S )N-02dz-15ShopF)r   merchant_normalizedr   	is_credit
account_idr   )r	   r   r   r   r   r   r   r   )r#   r   r   r   r   txns         r   _make_transactionr-   #   se    
vQuSk%"s6{#77FFC KKOOCKKJr   c                   $    e Zd Zd Zd Zd Zd Zy)TestMonthPickerc                    t        j                         }|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                  |      dz  }dd|iz  }	t        t	        j                  |	            d x}x}}|j                  }d	} ||      }
|
j                  } |       }|j                  }||v }|s>t	        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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}x}
x}x}x}}y )N	/budgets/   ==z3%(py2)s
{%(py2)s = %(py0)s.status_code
} == %(py5)sresponsepy0py2py5assert %(py7)spy7%Y-%minz%(py10)s
{%(py10)s = %(py8)s
{%(py8)s = %(py6)s
{%(py6)s = %(py2)s
{%(py2)s = %(py0)s.strftime
}(%(py4)s)
}.encode
}()
} in %(py14)s
{%(py14)s = %(py12)s.data
}todayr8   r9   py4py6py8py10py12py14assert %(py16)spy16r   rA   getstatus_code
@pytest_ar_call_reprcompare@py_builtinslocals_should_repr_global_name	_safereprAssertionError_format_explanationstrftimeencodedataselfclientr   rA   r6   @py_assert1@py_assert4@py_assert3@py_format6@py_format8@py_assert5@py_assert7@py_assert9@py_assert13@py_assert11@py_format15@py_format17s                    r   test_default_is_current_monthz-TestMonthPicker.test_default_is_current_month2   su   

::k*##*s*#s****#s******x***x***#***s*******~~@g@~g&@&--@-/@8==@/=@@@@/=@@@@@@u@@@u@@@~@@@g@@@&@@@-@@@/@@@@@@8@@@8@@@=@@@@@@@@r   c                 r   t               }t        |ddd       |j                  d      }d}|j                  }||v }|st	        j
                  d|fd||f      t	        j                  |      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}|j                  }||v }|st	        j
                  d|fd||f      t	        j                  |      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}}y )N     200.00r1      2025r>   z,%(py1)s in %(py5)s
{%(py5)s = %(py3)s.data
}r6   py1py3r:   r;   r<   s   March)r   r   rL   rX   rN   rO   rS   rP   rQ   rR   rT   rU   )
rZ   r[   r   r   r6   @py_assert0r]   @py_assert2r_   r`   s
             r   (test_picker_shows_month_with_budget_dataz8TestMonthPicker.test_picker_shows_month_with_budget_data8   s    S$8,::k*'(--'w-''''w-'''w''''''('''('''-'''''''(8==(x=((((x=(((x((((((8(((8(((=(((((((r   c                    t               }t               }t        ||ddd       |j                  d      }d}|j                  }||v }|st        j                  d|fd||f      t        j                  |      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}|j                  }||v }|st        j                  d|fd||f      t        j                  |      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}}y )Nrj      z50.00r1   rm   r>   rn   r6   ro   r;   r<   s   June)r   r$   r-   rL   rX   rN   rO   rS   rP   rQ   rR   rT   rU   rZ   r[   r   r   r#   r6   rr   r]   rs   r_   r`   s              r   -test_picker_shows_month_with_transaction_dataz=TestMonthPicker.test_picker_shows_month_with_transaction_data?   s	   $T1g6::k*'(--'w-''''w-'''w''''''('''('''-''''''''(--'w-''''w-'''w''''''('''('''-'''''''r   c                 ^   t        j                         }|j                  d      }|j                  }d} ||      }|j                  } |       }	|j
                  }
|	|
v }|s>t        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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}x}x}x}	x}}
y )
Nr1   %Yr>   r@   rA   r6   rB   rI   rJ   )r   rA   rL   rV   rW   rX   rN   rO   rP   rQ   rR   rS   rT   rU   )rZ   r[   r   rA   r6   r\   r^   ra   rb   rc   rd   re   rf   rg   s                 r   )test_picker_includes_current_month_alwaysz9TestMonthPicker.test_picker_includes_current_month_alwaysG   s   

::k*~~=d=~d#=#**=*,==,====,======u===u===~===d===#===*===,====================r   N)__name__
__module____qualname__rh   rt   rx   r{    r   r   r/   r/   1   s    A)(>r   r/   c                   6    e Zd Zd Zd Zd Zd Zd Zd Zd Z	y)	TestHistoricalViewc                 v   t        d      }t        |ddd       |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                  |      d
z  }dd|iz  }	t        t	        j                  |	            d x}x}}d}
|j                  }|
|v }|st	        j
                  d|fd|
|f      t	        j                  |
      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}}y )NHousingrj      z1200.00z/budgets/?month=2025-04r2   r3   r5   r6   r7   r;   r<   s   1200r>   rn   ro   r   r   rL   rM   rN   rO   rP   rQ   rR   rS   rT   rU   rX   rZ   r[   r   r   r6   r\   r]   r^   r_   r`   rr   rs   s               r   #test_month_param_selects_past_monthz6TestHistoricalView.test_month_param_selects_past_monthN   s   Y'S$9-::78##*s*#s****#s******x***x***#***s*******'(--'w-''''w-'''w''''''('''('''-'''''''r   c                    t                |j                  d      }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  }|j                  |       |	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  }|j                  |       t	        j                  |d      i z  }dd|iz  }t        t	        j                  |            d x}
x}x}x}	x}x}x}x}x}x}x}}y )N/budgets/?month=2020-01	   read-onlys
   historicalr>   z`%(py3)s in %(py11)s
{%(py11)s = %(py9)s
{%(py9)s = %(py7)s
{%(py7)s = %(py5)s.data
}.lower
}()
}r6   rq   r:   r<   py9py11%(py13)spy13zf%(py16)s in %(py24)s
{%(py24)s = %(py22)s
{%(py22)s = %(py20)s
{%(py20)s = %(py18)s.data
}.lower
}()
}rJ   py18py20py22py24%(py26)spy26   zassert %(py29)spy29)r   rL   rX   lowerrN   rO   rS   rP   rQ   rR   append_format_booloprT   rU   )rZ   r[   r   r6   r\   rs   @py_assert6@py_assert8@py_assert10r]   rr   @py_assert15@py_assert19@py_assert21@py_assert23@py_assert17@py_format12@py_format14@py_format25@py_format27@py_format28@py_format30s                         r   &test_past_month_shows_read_only_noticez9TestHistoricalView.test_past_month_shows_read_only_noticeU   sc   ::78^|^x}}^}22^24^|44^^^I\I\^I\I^^I^8^^^^^|4^^^|^^^^^^x^^^x^^^}^^^2^^^4^^^^^^^I^^^^^^^^^^^^^^^^^^^I\^^^I^^^^^^^^^^^^^^^^r   c                 V   t                |j                  d      }d}|j                  }||v }|st        j                  d|fd||f      t        j
                  |      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	}|j                  }||v }|st        j                  d|fd||f      t        j
                  |      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}}y )
Nz/budgets/?month=2024-11s   Novemberr>   rn   r6   ro   r;   r<   s   2024)r   rL   rX   rN   rO   rS   rP   rQ   rR   rT   rU   )	rZ   r[   r   r6   rr   r]   rs   r_   r`   s	            r   (test_past_month_shows_correct_month_namez;TestHistoricalView.test_past_month_shows_correct_month_nameZ   s    ::78+hmm+{m++++{m+++{++++++h+++h+++m+++++++'(--'w-''''w-'''w''''''('''('''-'''''''r   c                    t                |j                  d      }g }d}|j                  }||v }|}|sd}	|j                  }
|	|
v }|}|st        j                  d|fd||f      t        j
                  |      dt        j                         v st        j                  |      rt        j
                  |      ndt        j
                  |      dz  }dd	|iz  }|j                  |       |st        j                  dfd
	
f      t        j
                  |	      dt        j                         v st        j                  |      rt        j
                  |      ndt        j
                  |
      dz  }dd|iz  }|j                  |       t        j                  |d      i z  }dd|iz  }t        t        j                  |            d x}x}x}x}x}x}	x}}
y )Nr      Current month   current monthr>   )z,%(py3)s in %(py7)s
{%(py7)s = %(py5)s.data
}r6   )rq   r:   r<   z%(py9)sr   )z0%(py12)s in %(py16)s
{%(py16)s = %(py14)s.data
})rG   rH   rJ   z%(py18)sr   r   zassert %(py21)spy21)r   rL   rX   rN   rO   rS   rP   rQ   rR   r   r   rT   rU   )rZ   r[   r   r6   r\   rs   r   r]   rr   re   r   rd   r`   @py_format10rg   @py_format19@py_format20@py_format22s                     r   ,test_current_month_link_shown_for_past_monthz?TestHistoricalView.test_current_month_link_shown_for_past_month`   s   ::78UU8==U=0U4DUU4D4UUUUU=UUUUUUUUU8UUU8UUU=UUUUUUU4DUUU4D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Ur   c                     t        j                         }|j                  d|j                  d             }d}|j                  }||v}|st        j                  d|fd||f      t        j                  |      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}}y )
Nz/budgets/?month=r=   r   not inz0%(py1)s not in %(py5)s
{%(py5)s = %(py3)s.data
}r6   ro   r;   r<   )r   rA   rL   rV   rX   rN   rO   rS   rP   rQ   rR   rT   rU   )
rZ   r[   r   rA   r6   rr   r]   rs   r_   r`   s
             r   0test_current_month_link_hidden_for_current_monthzCTestHistoricalView.test_current_month_link_hidden_for_current_monthe   s    

:: 01H0IJK4x}}4}4444}444444444x444x444}4444444r   c                    t        j                         }|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                  |      dz  }dd|iz  }	t        t	        j                  |	            d x}x}}|j                  }d	} ||      }
|
j                  } |       }|j                  }||v }|s>t	        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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}x}
x}x}x}}y )Nz/budgets/?month=not-a-dater2   r3   r5   r6   r7   r;   r<   rz   r>   r@   rA   rB   rI   rJ   rK   rY   s                    r   .test_invalid_month_param_falls_back_to_currentzATestHistoricalView.test_invalid_month_param_falls_back_to_currentj   sv   

:::;##*s*#s****#s******x***x***#***s*******~~=d=~d#=#**=*,==,====,======u===u===~===d===#===*===,====================r   c                 t   t               }t        |ddd       |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                  |      d	z  }d
d|iz  }	t        t	        j                  |	            d x}x}}d}
|j                  }|
|v }|st	        j
                  d|fd|
|f      t	        j                  |
      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}}y )Nrj      z500.00z/budgets/?month=2025-02r2   r3   r5   r6   r7   r;   r<   s   2025-02r>   rn   ro   r   r   s               r   test_url_is_bookmarkablez+TestHistoricalView.test_url_is_bookmarkablep   s   S$8,::78##*s*#s****#s******x***x***#***s********X]]*z]****z]***z******X***X***]*******r   N)
r|   r}   r~   r   r   r   r   r   r   r   r   r   r   r   r   M   s'    (_
(V
5
>+r   r   c                       e Zd Zd Zd Zy)TestHistoricalReadOnlyc                    t               }|j                  d|j                  ddd      }g }d}|j                  }|j                  } |       }	||	v }
|
}|
sPd}|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  }|j                  |       |
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  }|j                  |       |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  }|j                  |       t        j                  |d      i z  }dd|iz  }t        t        j                  |            d x}x}x}x}
x}x}x}	x}x}x}x}x}x}x}x}x}}y )Nr   100.00r   r   T)rX   follow_redirectsr   r   s   onlyr>   r   r6   r   r   r   r   r   r   r   )zf%(py29)s in %(py37)s
{%(py37)s = %(py35)s
{%(py35)s = %(py33)s
{%(py33)s = %(py31)s.data
}.lower
}()
})r   py31py33py35py37z%(py39)spy39r   zassert %(py42)spy42)r   postr   rX   r   rN   rO   rS   rP   rQ   rR   r   r   rT   rU   )rZ   r[   r   r   r6   r\   rs   r   r   r   r]   rr   r   r   r   r   r   @py_assert28@py_assert32@py_assert34@py_assert36@py_assert30r   r   r   r   @py_format38@py_format40@py_format41@py_format43s                                 r   ,test_post_to_past_month_redirects_with_errorzCTestHistoricalReadOnly.test_post_to_past_month_redirects_with_errory   s   ;;%!$8<!  

 	F  	F8==  	F=#6#6  	F#6#8  	F#88  	FL  	FHMM  	FML_L_  	FL_La  	FLLa<a  	Fel  	Fpxp}p}  	Fp}  qD  qD  	F  qD  qF  	Fel  qF  fF  	F  	F  	F  	F#8  	F  	F  	F  	F  	F  	F  	F  	F  	F8  	F  	F  	F8  	F  	F  	F=  	F  	F  	F#6  	F  	F  	F#8  	F  	F  	F  	F  	F  	F  	FLLa  	F  	F  	FL  	F  	F  	F  	F  	F  	FH  	F  	F  	FH  	F  	F  	FM  	F  	F  	FL_  	F  	F  	FLa  	F  	F  	F  	F  	F  	F  	Fel  qF  	F  	F  	Fel  	F  	F  	F  	F  	F  	Fpx  	F  	F  	Fpx  	F  	F  	Fp}  	F  	F  	F  qD  	F  	F  	F  qF  	F  	F  	F  	F  	F  	F  	F  	F  	F  	F  	F  	F  	F  	F  	F  	F  	Fr   c                 ,   t               }|j                  d|j                  dd       t        j                  }|j
                  }|j                  }d}d} ||||      }	|	j                  }
 |
       }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                  |      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      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}x}	x}
x}x}}y )Nr   r   r   )rX   i  r   )r   r   r   r   r3   )z%(py17)s
{%(py17)s = %(py15)s
{%(py15)s = %(py13)s
{%(py13)s = %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.query
}.filter_by
}(category_id=%(py7)s
{%(py7)s = %(py5)s.id
}, year=%(py9)s, month=%(py11)s)
}.count
}()
} == %(py20)sr   r   )r8   r9   rC   r:   r<   r   r   r   py15py17r   zassert %(py22)sr   )r   r   r   r   query	filter_bycountrN   rO   rP   rQ   rR   rS   rT   rU   )rZ   r[   r   r   r\   r^   r   r   r   @py_assert12@py_assert14@py_assert16r   @py_assert18@py_format21@py_format23s                   r   %test_post_to_past_month_does_not_savez<TestHistoricalReadOnly.test_post_to_past_month_does_not_save   sW   %!$8< 	 	
 ||Z|%%Z#&&ZtZ1Z%&t1MZMSSZSUZYZZUYZZZZZUYZZZZZZZvZZZvZZZ|ZZZ%ZZZZZZ#ZZZ#ZZZ&ZZZtZZZ1ZZZMZZZSZZZUZZZYZZZZZZZZZZr   N)r|   r}   r~   r   r   r   r   r   r   r   x   s    F[r   r   c                       e Zd Zd Zd Zy)TestHistoricalActualsc                    t        d      }t               }t        |ddd       t        ||ddd       |j	                  d      }d}|j
                  }||v }|st        j                  d|fd	||f      t        j                  |      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}|j
                  }||v }|st        j                  d|fd	||f      t        j                  |      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}}y )NDiningrj      300.00z75.00/budgets/?month=2025-05s   75r>   rn   r6   ro   r;   r<   s   300r   r$   r   r-   rL   rX   rN   rO   rS   rP   rQ   rR   rT   rU   rw   s              r   $test_actuals_show_for_selected_monthz:TestHistoricalActuals.test_actuals_show_for_selected_month   s   X&S$8,$T1g6::78%%u%%%%u%%%u%%%%%%%%%%%%%%%%%%%&&v&&&&v&&&v&&&&&&&&&&&&&&&&&&&r   c                    t        d      }t               }t        |ddd       t        ||ddd       |j	                  d      }d}|j
                  }||v}|st        j                  d	|fd
||f      t        j                  |      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}}y )Nr   rj   r   r   rv   z999.00r   s   999r   r   r6   ro   r;   r<   r   rw   s              r   'test_actuals_do_not_bleed_across_monthsz=TestHistoricalActuals.test_actuals_do_not_bleed_across_months   s    X&S$8,$T1h7::78*X]]*v]****v]***v******X***X***]*******r   N)r|   r}   r~   r   r   r   r   r   r   r      s    '+r   r   c                   *    e Zd Zd Zd Zd Zd Zd Zy)TestBudgetsApiMonthParamc                    t        d      }t        j                         }t        ||j                  |j
                  d       |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                  |      dz  }	d	d
|	iz  }
t        t        j                  |
            d x}x}}|j!                         }t#        d |D        d       }d }||u}|st        j                  d|fd||f      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}}|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}}y )N	Groceriesrl   z/api/budgetsr2   r3   r5   r6   r7   r;   r<   c              3   2   K   | ]  }|d    dk(  s|  ywcategoryr   Nr   .0ds     r   	<genexpr>zUTestBudgetsApiMonthParam.test_api_returns_current_month_by_default.<locals>.<genexpr>        JQz]k-I!J   is notz%(py0)s is not %(py3)s	groceriesr8   rq   assert %(py5)sr:   budgetedg      i@z%(py1)s == %(py4)srp   rC   assert %(py6)srD   )r   r   rA   r   r   r   rL   rM   rN   rO   rP   rQ   rR   rS   rT   rU   get_jsonnext)rZ   r[   r   r   rA   r6   r\   r]   r^   r_   r`   rX   r  rs   @py_format4rr   @py_format5@py_format7s                     r   )test_api_returns_current_month_by_defaultzBTestBudgetsApiMonthParam.test_api_returns_current_month_by_default   sx   [)

S%**ekk8<::n-##*s*#s****#s******x***x***#***s*******  "JTJDQ	 $$y$$$$y$$$$$$y$$$y$$$$$$$$$$$--$----$---$----------r   c                 x   t        d      }t        |ddd       |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                  |      d
z  }dd|iz  }	t        t	        j                  |	            d x}x}}|j                         }
t        d |
D        d       }d }||u}|st	        j
                  d|fd||f      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}}|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}}y )Nr   rj   rk   1500.00/api/budgets?month=2025-03r2   r3   r5   r6   r7   r;   r<   c              3   2   K   | ]  }|d    dk(  s|  ywr   r   Nr   r   s     r   r   zHTestBudgetsApiMonthParam.test_api_accepts_month_param.<locals>.<genexpr>        Fa1Z=I+EFr   r   r   housingr  r  r:   r       p@r  r  r  rD   )r   r   rL   rM   rN   rO   rP   rQ   rR   rS   rT   rU   r  r	  )rZ   r[   r   r   r6   r\   r]   r^   r_   r`   rX   r  rs   r
  rr   r  r  s                    r   test_api_accepts_month_paramz5TestBudgetsApiMonthParam.test_api_accepts_month_param   sf   Y'S$9-:::;##*s*#s****#s******x***x***#***s*******  "F4FM""wd""""wd""""""w"""w"""d"""""""z",f,"f,,,,"f,,,",,,f,,,,,,,r   c                    t        d      }t        |ddd       t        |ddd       |j                  d      }|j                         }t	        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}	}y )Nr   rj   rk   r  r   z2000.00r  c              3   2   K   | ]  }|d    dk(  s|  ywr  r   r   s     r   r   z[TestBudgetsApiMonthParam.test_api_month_param_does_not_leak_other_months.<locals>.<genexpr>   r  r   r  r  r3   r  r  r  rD   )
r   r   rL   r  r	  rN   rO   rS   rT   rU   )rZ   r[   r   r   r6   rX   r  rr   r^   rs   r  r  s               r   /test_api_month_param_does_not_leak_other_monthszHTestBudgetsApiMonthParam.test_api_month_param_does_not_leak_other_months   s    Y'S$9-S$9-:::;  "F4FMz",f,"f,,,,"f,,,",,,f,,,,,,,r   c                    |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                  |      dz  }dd|iz  }t        t        j                  |            d x}x}}y )	Nz/api/budgets?month=bad-valuer2   r3   r5   r6   r7   r;   r<   )
rL   rM   rN   rO   rP   rQ   rR   rS   rT   rU   )	rZ   r[   r   r6   r\   r]   r^   r_   r`   s	            r   ,test_api_invalid_month_falls_back_to_currentzETestBudgetsApiMonthParam.test_api_invalid_month_falls_back_to_current   s    ::<=##*s*#s****#s******x***x***#***s*******r   c                    t        d      }t               }t        |ddd       t        ||ddd       |j	                  d      }|j                         }t        d |D        d       }|d   }t        j                  }	d	}
 |	|
      }||k(  }|st        j                  d
|fd||f      t        j                  |      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}	x}
}y )Nr   rj      z400.00z120.00z/api/budgets?month=2025-07c              3   2   K   | ]  }|d    dk(  s|  ywr   r   r   s     r   r   zOTestBudgetsApiMonthParam.test_api_includes_actuals_for_month.<locals>.<genexpr>   r   r   spentg      ^@r3   )zL%(py1)s == %(py9)s
{%(py9)s = %(py5)s
{%(py5)s = %(py3)s.approx
}(%(py7)s)
}pytest)rp   rq   r:   r<   r   zassert %(py11)sr   )r   r$   r   r-   rL   r  r	  r   approxrN   rO   rS   rP   rQ   rR   rT   rU   )rZ   r[   r   r   r#   r6   rX   r  rr   r]   r   r   rs   r   r   s                  r   #test_api_includes_actuals_for_monthz<TestBudgetsApiMonthParam.test_api_includes_actuals_for_month   s    [)S$8,$T1h7:::;  "JTJDQ	!9V]]959]5%99!%99999!%9999!999999V999V999]9995999%999999999r   N)r|   r}   r~   r  r  r  r  r"  r   r   r   r   r      s    	.--+:r   r   )r   ) __doc__builtinsrP   _pytest.assertion.rewrite	assertionrewriterN   decimalr   datetimer   r   app.extensionsr   r   app.models.budgetr   app.models.categoryr   app.models.accountr   app.models.transactionr	   r   r   r$   r-   r/   r   r   r   r   r   r   r   <module>r/     sn    2       $ $ ( & .> >8(+ (+V[ [&+ +&+: +:r   