
    62j                        d Z ddlZddlmc 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  e	j"                         d        Z e	j"                         d        Z G d	 d
      Z G d d      Z G d d      Z G d d      Zy)u  
Dashboard first-run / empty-state experience — Story 3.7.

The dashboard now shows 5 widgets with inline empty states rather than
a separate "Getting Started" checklist. These tests verify the empty-state
behaviour within each widget and the presence of onboarding CTAs.
    N)Decimal)db)Account)Transactionc                     t        ddd      }t        j                  j                  |       t        j                  j	                          |S )NChasecheckingT)nametype	is_active)r   _dbsessionaddcommit)r   as     J/var/www/html/financials/tests/test_blueprints/test_dashboard_first_run.pyacctr      s5    W:>AKKOOAKKH    c                     t        dddt        d      |j                  d      }t        j                  j                  |       t        j                  j                          |S )Nz
2026-05-15ALDIz29.99T)datemerchant_normalizedmerchant_rawamount
account_id	is_manual)r   r   idr   r   r   r   )r   r   ts      r   txnr      sN    "w77	A KKOOAKKHr   c                       e Zd Zd Zd Zy)TestDashboardBasicc                    |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 	N/   ==z3%(py2)s
{%(py2)s = %(py0)s.status_code
} == %(py5)sresponsepy0py2py5assert %(py7)spy7
getstatus_code
@pytest_ar_call_reprcompare@py_builtinslocals_should_repr_global_name	_safereprAssertionError_format_explanation	selfclientr   r)   @py_assert1@py_assert4@py_assert3@py_format6@py_format8s	            r   test_returns_200z#TestDashboardBasic.test_returns_200-       ::c?##*s*#s****#s******x***x***#***s*******r   c                    |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$   s	   Dashboardinz,%(py1)s in %(py5)s
{%(py5)s = %(py3)s.data
}r)   py1py3r-   r.   r/   
r1   datar3   r4   r8   r5   r6   r7   r9   r:   	r<   r=   r   r)   @py_assert0r?   @py_assert2rA   rB   s	            r   test_has_page_titlez&TestDashboardBasic.test_has_page_title1   s|    ::c?,x}},|},,,,|},,,|,,,,,,x,,,x,,,},,,,,,,r   N)__name__
__module____qualname__rC   rQ    r   r   r!   r!   ,   s    +-r   r!   c                   0    e Zd Zd Zd Zd Zd Zd Zd Zy)TestFirstRunStatec                    |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}}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}}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	)z2Dashboard renders widget shells even with no data.r$   s   Budget BurnrF   rH   r)   rI   r.   r/   Ns   Monthly Spendings   Upcoming Billss   Recent Transactionss   Debt PaydownrL   rN   s	            r   test_shows_dashboard_widgetsz.TestFirstRunState.test_shows_dashboard_widgets9   s9   ::c?..~....~...~..................."3hmm3"m3333"m333"333333h333h333m3333333 1HMM1 M1111 M111 111111H111H111M1111111%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/(--/-////-/////////(///(///-///////r   c                    |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)z4Empty state widgets link to onboarding destinations.r$   s   account   transactionrF   )z`%(py3)s in %(py11)s
{%(py11)s = %(py9)s
{%(py9)s = %(py7)s
{%(py7)s = %(py5)s.data
}.lower
}()
}r)   )rK   r-   r/   py9py11z%(py13)spy13)zf%(py16)s in %(py24)s
{%(py24)s = %(py22)s
{%(py22)s = %(py20)s
{%(py20)s = %(py18)s.data
}.lower
}()
})py16py18py20py22py24z%(py26)spy26   zassert %(py29)spy29Nr1   rM   lowerr3   r4   r8   r5   r6   r7   append_format_boolopr9   r:   )r<   r=   r   r)   r>   rP   @py_assert6@py_assert8@py_assert10r?   rO   @py_assert15@py_assert19@py_assert21@py_assert23@py_assert17@py_format12@py_format14@py_format25@py_format27@py_format28@py_format30s                         r   %test_shows_account_or_transaction_ctaz7TestFirstRunState.test_shows_account_or_transaction_ctaB   s[   ::c?]z]X]]]]00]02]z22]n]]H[H[]H[H]]nH]6]]]]]z2]]]z]]]]]]X]]]X]]]]]]]0]]]2]]]]]]]nH]]]]n]]]]]]]]]]]]]]]H[]]]H]]]]]]]]]]]]]]]]r   c                    |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)z;At least one link to settings (accounts) appears somewhere.r$   s	   /settings   /transactionsrF   z,%(py3)s in %(py7)s
{%(py7)s = %(py5)s.data
}r)   rK   r-   r/   %(py9)sr\   z0%(py12)s in %(py16)s
{%(py16)s = %(py14)s.data
}py12py14r_   %(py18)sr`   re   assert %(py21)spy21Nr1   rM   r3   r4   r8   r5   r6   r7   ri   rj   r9   r:   r<   r=   r   r)   r>   rP   rk   r?   rO   @py_assert11rn   @py_assert13rB   @py_format10@py_format17@py_format19@py_format20@py_format22s                     r   'test_shows_link_to_accounts_or_settingsz9TestFirstRunState.test_shows_link_to_accounts_or_settingsG   s    ::c?Q|Qx}}Q|},Q0@QHMMQ0@M0QQQQQ|}QQQ|QQQQQQxQQQxQQQ}QQQQQQQ0@MQQQ0@QQQQQQHQQQHQQQMQQQQQQQQQQQQQQr   c                 2   |j                  d      }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  }
t        t        j                  |
            d x}x}x}x}}y )	Nr$   r[   rF   )z^%(py1)s in %(py9)s
{%(py9)s = %(py7)s
{%(py7)s = %(py5)s
{%(py5)s = %(py3)s.data
}.lower
}()
}r)   )rJ   rK   r-   r/   r\   zassert %(py11)sr]   )r1   rM   rh   r3   r4   r8   r5   r6   r7   r9   r:   )r<   r=   r   r)   rO   r?   rk   rl   rP   r   rs   s              r   test_shows_add_transaction_stepz1TestFirstRunState.test_shows_add_transaction_stepL   s    ::c?66!4!46!4!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!4666!666666666r   c                    |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$   s   /transactions/creater{   rF   r|   r)   r}   r~   r\   r   r   r   r`   re   r   r   r   r   s                     r   %test_shows_link_to_create_transactionz7TestFirstRunState.test_shows_link_to_create_transactionP      ::c?\&\(--\&-7\;K\x}}\;K};\\\\\&-\\\&\\\\\\(\\\(\\\-\\\\\\\;K}\\\;K\\\\\\x\\\x\\\}\\\\\\\\\\\\\\r   c                 "   |j                  d      }g }d}|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
                  |      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}}y )Nr$      No transactionss   no transactionsrF   r|   r)   r}   r~   r\   )zf%(py12)s in %(py20)s
{%(py20)s = %(py18)s
{%(py18)s = %(py16)s
{%(py16)s = %(py14)s.data
}.lower
}()
})r   r   r_   r`   ra   z%(py22)srb   re   zassert %(py25)spy25rg   )r<   r=   r   r)   r>   rP   rk   r?   rO   r   rn   rr   ro   r   rB   r   @py_format21@py_format23@py_format24@py_format26s                       r   .test_no_transactions_shows_empty_state_messagez@TestFirstRunState.test_no_transactions_shows_empty_state_messageT   s5   ::c?a!aX]]a!]2a6HaHMMaML_L_aL_Laa6HLa6aaaaa!]aaa!aaaaaaXaaaXaaa]aaaaaaa6HLaaaa6HaaaaaaHaaaHaaaMaaaL_aaaLaaaaaaaaaaaaaaaar   N)	rR   rS   rT   rY   ry   r   r   r   r   rU   r   r   rW   rW   8   s$    0^
R
7]br   rW   c                   $    e Zd Zd Zd Zd Zd Zy)TestStepCompletionc                    |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 r#   r0   )
r<   r=   r   r   r)   r>   r?   r@   rA   rB   s
             r   (test_account_step_reflected_in_dashboardz;TestStepCompletion.test_account_step_reflected_in_dashboard\   rD   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 r#   r0   r;   s	            r   &test_dashboard_renders_without_accountz9TestStepCompletion.test_dashboard_renders_without_account`   rD   r   c                    |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$   r   s   AddrF   r|   r)   r}   r~   r\   r   r   r   r`   re   r   r   r   )r<   r=   r   r   r)   r>   rP   rk   r?   rO   r   rn   r   rB   r   r   r   r   r   s                      r   5test_transaction_step_incomplete_without_transactionszHTestStepCompletion.test_transaction_step_incomplete_without_transactionsd   s    ::c?M!MX]]M!]2MfMMf6MMMMM!]MMM!MMMMMMXMMMXMMM]MMMMMMMfMMMfMMMMMMMMMMMMMMMMMMMMMMMMMMr   c                 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 )Nr$   r%   r&   r(   r)   r*   r.   r/      ALDIrF   rH   rI   )r1   r2   r3   r4   r5   r6   r7   r8   r9   r:   rM   )r<   r=   r   r   r)   r>   r?   r@   rA   rB   rO   rP   s               r   6test_transaction_step_complete_when_transaction_existszITestStepCompletion.test_transaction_step_complete_when_transaction_existsh   s    ::c?##*s*#s****#s******x***x***#***s*******'(--'w-''''w-'''w''''''('''('''-'''''''r   N)rR   rS   rT   r   r   r   r   rU   r   r   r   r   [   s    ++N(r   r   c                   $    e Zd Zd Zd Zd Zd Zy)TestUpAndRunningStatec                    |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$   r   rF   rH   r)   rI   r.   r/   rL   
r<   r=   r   r   r)   rO   r?   rP   rA   rB   s
             r   )test_transaction_appears_in_recent_widgetz?TestUpAndRunningState.test_transaction_appears_in_recent_widgetr   s|    ::c?'(--'w-''''w-'''w''''''('''('''-'''''''r   c                    |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$   s   No transactions yet)not in)z0%(py1)s not in %(py5)s
{%(py5)s = %(py3)s.data
}r)   rI   r.   r/   rL   r   s
             r   ?test_does_not_show_empty_state_for_transactions_when_txns_existzUTestUpAndRunningState.test_does_not_show_empty_state_for_transactions_when_txns_existv   s    ::c?%:X]]:%]::::%]:::%::::::X:::X:::]:::::::r   c                    |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$   r{   rF   rH   r)   rI   r.   r/   rL   r   s
             r   $test_shows_link_to_transactions_listz:TestUpAndRunningState.test_shows_link_to_transactions_list{   s    ::c?08==0=0000=00000000080008000=0000000r   c                    |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 r   r   r   s                     r   "test_shows_link_to_add_transactionz8TestUpAndRunningState.test_shows_link_to_add_transaction   r   r   N)rR   rS   rT   r   r   r   r   rU   r   r   r   r   q   s    (;
1]r   r   )__doc__builtinsr5   _pytest.assertion.rewrite	assertionrewriter3   decimalr   pytestapp.extensionsr   r   app.models.accountr   app.models.transactionr   fixturer   r   r!   rW   r   r   rU   r   r   <module>r      s        $ & .
     - -b bF( (,] ]r   