
    5j-                     8   d Z ddlZddlmc mZ ddlmZ ddl	m
Z
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
lmZ d ZddZddZddZ G d d      Z G d d      Z G d d      Z  G d d      Z! G d d      Z" G d d      Z# G d d      Z$y) u-   Analytics & Insights — Stories 10.1–10.7.    N)Decimal)date	timedelta)db)Account)Category)Transaction)Budget)Settingsc                      t        ddd      } t        j                  j                  |        t        j                  j	                          | S )NCheckingcheckingT)nametype	is_active)r   _dbsessionaddcommit)as    @/var/www/html/financials/tests/test_blueprints/test_analytics.py_make_accountr      s5    ZjDAAKKOOAKKH    c                     t        | dd      }t        j                  j                  |       t        j                  j	                          |S )NT)r   	is_systemr   )r   r   r   r   r   )r   cats     r   _make_categoryr      s5    

=CKKOOCKKJr   c           	      <   t        j                         t        |      z
  j                         }t	        ||t        |      |d| j                  |j                        }t        j                  j                  |       t        j                  j                          |S )NdaysTr   merchant_normalizedamount	is_credit	is_manual
account_idcategory_id)r   todayr   	isoformatr	   r   idr   r   r   r   )acctr   r#   merchantdays_agor$   dts           r   	_make_txnr0      sn    		x0	0;;=AHv)t77	A
 KKOOAKKHr   c                    t         j                  j                         }|6t        dt        |             }t        j
                  j                  |       nt        |       |_        t        j
                  j                          y )N   )r*   monthly_income)	r   queryfirstr   r   r   r   r3   r   )r#   ss     r   _set_incomer7   +   sU    Ay'&/:"6?KKr   c                   *    e Zd Zd Zd Zd Zd Zd Zy)TestAnalyticsShellc           	      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                  |      t        j                  |      t        j                  |      t        j                  |      dz  }	dd|	iz  }
t        t        j                  |
            d x}x}x}x}x}}y )	N/analytics/   ==zk%(py8)s
{%(py8)s = %(py6)s
{%(py6)s = %(py2)s
{%(py2)s = %(py0)s.get
}(%(py4)s)
}.status_code
} == %(py11)sclientpy0py2py4py6py8py11assert %(py13)spy13
getstatus_code
@pytest_ar_call_reprcompare@py_builtinslocals_should_repr_global_name	_safereprAssertionError_format_explanationselfr@   r   @py_assert1@py_assert3@py_assert5@py_assert7@py_assert10@py_assert9@py_format12@py_format14s              r   test_analytics_returns_200z-TestAnalyticsShell.test_analytics_returns_2008   s    zz;-;z-(;(44;;4;;;;4;;;;;;v;;;v;;;z;;;-;;;(;;;4;;;;;;;;;;;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   Month over Monthinz,%(py1)s in %(py5)s
{%(py5)s = %(py3)s.data
}responsepy1py3py5assert %(py7)spy7
rK   datarM   rN   rR   rO   rP   rQ   rS   rT   	rV   r@   r   rd   @py_assert0@py_assert4@py_assert2@py_format6@py_format8s	            r   test_analytics_shows_mom_widgetz2TestAnalyticsShell.test_analytics_shows_mom_widget;   s    ::m,"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3r   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   Year over Yearra   rc   rd   re   ri   rj   rk   rm   s	            r   test_analytics_shows_yoy_widgetz2TestAnalyticsShell.test_analytics_shows_yoy_widget?   s    ::m, 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1r   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   Spending by Categoryra   rc   rd   re   ri   rj   rk   rm   s	            r   +test_analytics_shows_spending_chart_sectionz>TestAnalyticsShell.test_analytics_shows_spending_chart_sectionC   s    ::m,&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7r   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;   s	   analyticsra   )z^%(py1)s in %(py9)s
{%(py9)s = %(py7)s
{%(py7)s = %(py5)s
{%(py5)s = %(py3)s.data
}.lower
}()
}rd   )rf   rg   rh   rj   py9zassert %(py11)srG   )rK   rl   lowerrM   rN   rR   rO   rP   rQ   rS   rT   )rV   r@   r   rd   rn   ro   @py_assert6@py_assert8rp   @py_format10r]   s              r   test_active_page_is_analyticsz0TestAnalyticsShell.test_active_page_is_analyticsG   s    ::m,4x}}4}224244|44444|4444|444444x444x444}4442444444444444r   N)__name__
__module____qualname__r_   rs   ru   rw   r~    r   r   r9   r9   7   s    <4285r   r9   c                   $    e Zd Zd Zd Zd Zd Zy)TestSpendingPatternsc                    |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	}
|
|	v }|st        j                  d
|fd|
|	f      t        j                  |
      dt	        j
                         v st        j                  |	      rt        j                  |	      nddz  }dd|iz  }t        t        j                  |            d x}
}d}
|
|	v }|st        j                  d
|fd|
|	f      t        j                  |
      dt	        j
                         v st        j                  |	      rt        j                  |	      nddz  }dd|iz  }t        t        j                  |            d x}
}d}
|
|	v }|st        j                  d
|fd|
|	f      t        j                  |
      dt	        j
                         v st        j                  |	      rt        j                  |	      nddz  }dd|iz  }t        t        j                  |            d x}
}y )N#/api/analytics/spending-by-categoryr<   r=   z3%(py2)s
{%(py2)s = %(py0)s.status_code
} == %(py5)srd   rB   rC   rh   ri   rj   labelsra   )z%(py1)s in %(py3)srl   )rf   rg   assert %(py5)srh   
categoriesseries)rK   rL   rM   rN   rO   rP   rQ   rR   rS   rT   get_json)rV   r@   r   rd   rW   ro   rX   rq   rr   rl   rn   rp   @py_format4s                r   *test_api_spending_by_category_returns_jsonz?TestSpendingPatterns.test_api_spending_by_category_returns_jsonO   s   ::CD##*s*#s****#s******x***x***#***s*******  "x4x4x44#|t####|t###|######t###t#######x4x4x44r   c                    t               }t        d      }t        ||d       |j                  d      }|j	                         }d}|d   }||v }	|	slt        j                  d|	fd||f      t        j                  |      t        j                  |      dz  }
dd	|
iz  }t        t        j                  |            d x}x}	}y )
NDiningz75.00r   r   ra   z%(py1)s in %(py4)srf   rD   assert %(py6)srE   )
r   r   r0   rK   r   rM   rN   rR   rS   rT   )rV   r@   r   r+   r   rd   rl   rn   rX   rp   @py_format5@py_format7s               r   3test_api_spending_by_category_includes_transactionszHTestSpendingPatterns.test_api_spending_by_category_includes_transactionsW   s    X&$W%::CD  "-4--x-----x----x-----------r   c           	      t   |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        |t              }
|
s3d	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t	        j
                         v st        j                  t              rt        j                  t              ndt        j                  |
      dz  }t        t        j                  |            d x}	x}}
y )N/api/analytics/monthly-totalsr<   r=   r   rd   r   ri   rj   zjassert %(py8)s
{%(py8)s = %(py0)s(%(py5)s
{%(py5)s = %(py3)s
{%(py3)s = %(py1)s.get_json
}()
}, %(py6)s)
}
isinstancelist)rB   rf   rg   rh   rE   rF   )rK   rL   rM   rN   rO   rP   rQ   rR   rS   rT   r   r   r   )rV   r@   r   rd   rW   ro   rX   rq   rr   rp   rZ   @py_format9s               r   $test_api_monthly_totals_returns_jsonz9TestSpendingPatterns.test_api_monthly_totals_returns_json_   s8   ::=>##*s*#s****#s******x***x***#***s*******"++4+-4z-t44444444z444z444444(444(444+444-444444t444t4444444444r   c                    t               }t               }t        ||d       |j                  d      }|j	                         }t        |      }d}||kD  }	|	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   }||v }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }
t        t        j                  |
            d x}x}}d}|d   }||v }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }
t        t        j                  |
            d x}x}}d}|d   }||v }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }
t        t        j                  |
            d x}x}}y )N100.00r   r   )>)z/%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} > %(py6)slenrl   )rB   rf   rg   rE   zassert %(py8)srF   yearra   r   r   r   rE   monthtotal)r   r   r0   rK   r   r   rM   rN   rO   rP   rQ   rR   rS   rT   )rV   r@   r   r+   r   rd   rl   rp   rY   ro   r   r   rn   rX   r   s                  r   +test_api_monthly_totals_has_expected_fieldsz@TestSpendingPatterns.test_api_monthly_totals_has_expected_fieldsd   s   $X&::=>  "4y1y1}y1ss44y1 a v    v   v          !$q'!w'!!!!w'!!!w!!!'!!!!!!!!$q'!w'!!!!w'!!!w!!!'!!!!!!!r   N)r   r   r   r   r   r   r   r   r   r   r   r   N   s     .5
	"r   r   c                       e Zd Zd Zd Zy)TestMoMYoYComparisonsc                    t               }t               }t        ||dd       t        ||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200.00   r-   150.00(   r;   r<   r=   r   rd   r   ri   rj   s   200ra   rc   re   )r   r   r0   rK   rL   rM   rN   rO   rP   rQ   rR   rS   rT   rl   )rV   r@   r   r+   r   rd   rW   ro   rX   rq   rr   rn   rp   s                r   test_mom_comparison_with_dataz3TestMoMYoYComparisons.test_mom_comparison_with_datas   s   $X2$X3::m,##*s*#s****#s******x***x***#***s*******&&v&&&&v&&&v&&&&&&&&&&&&&&&&&&&r   c                 4   |j                  d      }t        j                  } |       }|j                  }t	        |      }|j
                  } |       }	|j                  }
|	|
v }|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                  t              rt        j                  t              ndt        j                  |      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}	x}}
y )
Nr;   ra   )z%(py13)s
{%(py13)s = %(py11)s
{%(py11)s = %(py9)s
{%(py9)s = %(py0)s(%(py7)s
{%(py7)s = %(py5)s
{%(py5)s = %(py3)s
{%(py3)s = %(py1)s.today
}()
}.year
})
}.encode
}()
} in %(py17)s
{%(py17)s = %(py15)s.data
}strr   rd   )
rB   rf   rg   rh   rj   ry   rG   rI   py15py17zassert %(py19)spy19)rK   r   r(   r   r   encoderl   rM   rN   rO   rP   rQ   rR   rS   rT   )rV   r@   r   rd   rp   ro   r{   r|   r[   @py_assert12@py_assert16@py_assert14@py_format18@py_format20s                 r   test_yoy_shows_current_yearz1TestMoMYoYComparisons.test_yoy_shows_current_year|   s1   ::m,::?:<?<$$?s$%?%,,?,.?(--?.-????.-??????s???s??????4???4???:???<???$???%???,???.??????(???(???-????????r   N)r   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y)TestSubscriptionDetectorc           	      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                  |      t        j                  |      t        j                  |      t        j                  |      dz  }	dd|	iz  }
t        t        j                  |
            d x}x}x}x}x}}y )	N/analytics/subscriptionsr<   r=   r?   r@   rA   rH   rI   rJ   rU   s              r   #test_subscriptions_page_returns_200z<TestSubscriptionDetector.test_subscriptions_page_returns_200   s    zzH4Hz45H5AAHSHASHHHHASHHHHHHvHHHvHHHzHHH4HHH5HHHAHHHSHHHHHHHHr   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 subscriptionsra   rc   rd   re   ri   rj   rk   rm   s	            r   &test_subscriptions_empty_state_no_dataz?TestSubscriptionDetector.test_subscriptions_empty_state_no_data   s    ::89"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3r   c           
         ddl m} t               }t               }dD ]  }t	        j
                         t        d|z        z
  j                         }t        |dt        d      dd	|j                  |j                  
      }t        j                  j                  |        t        j                  j                          |j                  j!                         5   |       }	d d d        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  }t1        t%        j2                  |            d x}}|
j4                  }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  }t1        t%        j2                  |            d x}x}}y # 1 sw Y   xY w)Nr   )detect_subscriptionsr2            r   Netflixz15.99FTr!   c              3   @   K   | ]  }|j                   d k(  s|  yw)r   N)r,   ).0r6   s     r   	<genexpr>zMTestSubscriptionDetector.test_detects_monthly_subscription.<locals>.<genexpr>   s     Ca1::+BC   is notz%(py0)s is not %(py3)snetflixrB   rg   r   rh   monthlyr=   )z2%(py2)s
{%(py2)s = %(py0)s.recurrence
} == %(py5)sr   ri   rj   )+app.services.insights.subscription_detectorr   r   r   r   r(   r   r)   r	   r   r*   r   r   r   r   applicationapp_contextnextrM   rN   rO   rP   rQ   rR   rS   rT   
recurrence)rV   r@   r   r   r+   r   
months_agor.   r/   subsr   rp   rW   r   rq   ro   rX   rr   s                     r   !test_detects_monthly_subscriptionz:TestSubscriptionDetector.test_detects_monthly_subscription   s   T# 	J	rJ ??JJLAIw'5D77A
 KKOOA	 	++- 	*')D	*C4CTJ""wd""""wd""""""w"""w"""d"""""""!!.Y.!Y....!Y......w...w...!...Y.......		* 	*s   I++I5c                 "   t               }t               }dD ]  }t        j                         t	        d|z        z
  j                         }t        j                  j                  t        |dt        d      dd|j                  |j                                t        j                  j                          |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   r   Spotifyz9.99FTr!   r   s   Spotifyra   rc   rd   re   ri   rj   )r   r   r   r(   r   r)   r   r   r   r	   r   r*   r   rK   rl   rM   rN   rR   rO   rP   rQ   rS   rT   )rV   r@   r   r+   r   r   r.   rd   rn   ro   rp   rq   rr   s                r   *test_subscription_page_shows_detected_subszCTestSubscriptionDetector.test_subscription_page_shows_detected_subs   s   # 	J	rJ ??JJLAKKOOKIv%477 	 	::89*X]]*z]****z]***z******X***X***]*******r   N)r   r   r   r   r   r   r   r   r   r   r   r      s    I4/*+r   r   c                       e Zd Zd Zd Zd Zy)TestBadSpendingFlagsc                 ^   ddl m} t               }t        d      }t	        d       t        ||dd       |j                  j                         5   |t        d            }d d d        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}	}y # 1 sw Y   xY w)Nr   get_spending_flagsr   1000.00r   r   r   c              3   @   K   | ]  }|j                   d k(  s|  ywdining_entertainment_ratioN	flag_typer   fs     r   r   zFTestBadSpendingFlags.test_dining_entertainment_flag.<locals>.<genexpr>        \!?[0[A\r   r   r   dining_flagr   r   rh   )#app.services.insights.pattern_flagsr   r   r   r7   r0   r   r   r   r   rM   rN   rO   rP   rQ   rR   rS   rT   rV   r@   r   r   r+   diningflagsr   rp   rW   r   rq   s               r   test_dining_entertainment_flagz3TestBadSpendingFlags.test_dining_entertainment_flag   s    J)I$15++- 	;&wy'9:E	;\u\^bc"&&{$&&&&{$&&&&&&{&&&{&&&$&&&&&&&	; 	;s   D##D,c                 H   ddl m} t               }t        d      }t	        ||dd       |j
                  j                         5   |t        d            }d d d        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}	}y # 1 sw Y   xY w)Nr   r   r   50.00r   r   r   c              3   @   K   | ]  }|j                   d k(  s|  ywr   r   r   s     r   r   zHTestBadSpendingFlags.test_no_flags_when_within_budget.<locals>.<genexpr>   r   r   )is)z%(py0)s is %(py3)sr   r   r   rh   )r   r   r   r   r0   r   r   r   r   rM   rN   rO   rP   rQ   rR   rS   rT   r   s               r    test_no_flags_when_within_budgetz5TestBadSpendingFlags.test_no_flags_when_within_budget   s    J)$!4++- 	;&wy'9:E	;\u\^bc""{d""""{d""""""{"""{"""d"""""""	; 	;s   DD!c                    t               }t        d      }t        d       t        ||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}}y )Nr   z500.00r   r   r   r;   r<   r=   r   rd   r   ri   rj   )r   r   r7   r0   rK   rL   rM   rN   rO   rP   rQ   rR   rS   rT   )rV   r@   r   r+   r   rd   rW   ro   rX   rq   rr   s              r   test_analytics_shows_flagsz/TestBadSpendingFlags.test_analytics_shows_flags   s    )H$15::m,##*s*#s****#s******x***x***#***s*******r   N)r   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y)TestMerchantSpendSummaryc           	      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                  |      t        j                  |      t        j                  |      t        j                  |      dz  }	dd|	iz  }
t        t        j                  |
            d x}x}x}x}x}}y )	N/analytics/merchantsr<   r=   r?   r@   rA   rH   rI   rJ   rU   s              r   test_merchants_page_returns_200z8TestMerchantSpendSummary.test_merchants_page_returns_200   s    zzD0Dz01D1==DD=DDDD=DDDDDDvDDDvDDDzDDD0DDD1DDD=DDDDDDDDDDDr   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 merchant datara   rc   rd   re   ri   rj   rk   rm   s	            r   "test_merchants_empty_state_no_dataz;TestMerchantSpendSummary.test_merchants_empty_state_no_data   s    ::45"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3r   c                    t               }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 )Nr   Amazonr   r,   r-   r   Walmartr   r   s   Amazonra   rc   rd   re   ri   rj   s   Walmart)r   r   r0   rK   rl   rM   rN   rR   rO   rP   rQ   rS   rT   )rV   r@   r   r+   r   rd   rn   ro   rp   rq   rr   s              r   "test_merchants_shows_top_merchantsz;TestMerchantSpendSummary.test_merchants_shows_top_merchants   s   $X1E$Wy1E::45)HMM)yM))))yM)))y))))))H)))H)))M)))))))*X]]*z]****z]***z******X***X***]*******r   c                    t               }t               }t        ||ddd       t        ||ddd       t        j                         }|t        d	      z
  j                         }|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   
RecentShopr   r  r   OldShopr<   r   r   z/analytics/merchants?from=s
   RecentShopra   rc   rd   re   ri   rj   )r   r   r0   r   r(   r   r)   rK   rl   rM   rN   rR   rO   rP   rQ   rS   rT   )rV   r@   r   r+   r   r(   	from_daterd   rn   ro   rp   rq   rr   s                r   test_merchants_date_filterz3TestMerchantSpendSummary.test_merchants_date_filter   s    $XqI$X	CH

YB//::<	:: :9+FG--}----}---}-------------------r   N)r   r   r   r   r   r  r	  r   r   r   r   r      s    E4+.r   r   c                   *    e Zd Zd Zd Zd Zd Zd Zy)TestHistoryBasedRecommendationsc           	      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                  |      t        j                  |      t        j                  |      t        j                  |      dz  }	dd|	iz  }
t        t        j                  |
            d x}x}x}x}x}}y )	N/analytics/recommendationsr<   r=   r?   r@   rA   rH   rI   rJ   rU   s              r   %test_recommendations_page_returns_200zETestHistoryBasedRecommendations.test_recommendations_page_returns_200   s    zzJ6Jz67J7CCJsJCsJJJJCsJJJJJJvJJJvJJJzJJJ6JJJ7JJJCJJJsJJJJJJJJr   c                 "   |j                  d      }g }d}|j                  }|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
                  |      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
                  |      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  s   incomes   Settingsra   z`%(py3)s in %(py11)s
{%(py11)s = %(py9)s
{%(py9)s = %(py7)s
{%(py7)s = %(py5)s.data
}.lower
}()
}rd   rg   rh   rj   ry   rG   %(py13)srI   )z0%(py16)s in %(py20)s
{%(py20)s = %(py18)s.data
})py16py18py20z%(py22)spy22r2   zassert %(py25)spy25)rK   rl   rz   rM   rN   rR   rO   rP   rQ   append_format_booloprS   rT   )rV   r@   r   rd   rW   rp   r{   r|   r[   ro   rn   @py_assert15@py_assert19@py_assert17r]   r^   @py_format21@py_format23@py_format24@py_format26s                       r   test_no_income_shows_ctaz8TestHistoryBasedRecommendations.test_no_income_shows_cta   s/   :::;QyQHMMQM//Q/1Qy11Q[QHMMQ[M5QQQQQy1QQQyQQQQQQHQQQHQQQMQQQ/QQQ1QQQQQQQ[MQQQ[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QQr   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 )Nr  s   historys   monthsra   r  rd   r  r  rI   )zf%(py16)s in %(py24)s
{%(py24)s = %(py22)s
{%(py22)s = %(py20)s
{%(py20)s = %(py18)s.data
}.lower
}()
})r  r  r  r  py24z%(py26)spy26r2   zassert %(py29)spy29)r7   rK   rl   rz   rM   rN   rR   rO   rP   rQ   r  r  rS   rT   )rV   r@   r   rd   rW   rp   r{   r|   r[   ro   rn   r  r  @py_assert21@py_assert23r  r]   r^   @py_format25@py_format27@py_format28@py_format30s                         r   'test_insufficient_history_shows_messagezGTestHistoryBasedRecommendations.test_insufficient_history_shows_message   sb   :::;XzXX]]X]00X02Xz22XiX8==X=CVCVXCVCXXiCX6XXXXXz2XXXzXXXXXXXXXXXXXX]XXX0XXX2XXXXXXXiCXXXXiXXXXXX8XXX8XXX=XXXCVXXXCXXXXXXXXXXXXXXXXr   c                 "   t        d       t               }t        d      }dD ]  }t        ||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}	}y )N3000.00r   )
   r   z120.00r   r  r<   r=   r   rd   r   ri   rj   )r7   r   r   r0   rK   rL   rM   rN   rO   rP   rQ   rR   rS   rT   )rV   r@   r   r+   r   r-   rd   rW   ro   rX   rq   rr   s               r   +test_recommendations_generated_with_historyzKTestHistoryBasedRecommendations.test_recommendations_generated_with_history   s    IX&  	>HdCH=	>:::;##*s*#s****#s******x***x***#***s*******r   c           	         ddl m} ddlm} t	               }t        d      }dD ]  }t        ||d|        t        |d      r|j                  j                         nt        j                  j                  5   |t        d	            }d
d
d
       r`|D ]Y  }t        ||      }	|	s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dt        j                          v st#        j$                  |      rt#        j&                  |      ndt#        j&                  |	      dz  }
t)        t#        j*                  |
            d
}	|j,                  }t        |t              }|s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&                  |      dt        j                          v st#        j$                  t              rt#        j&                  t              ndt#        j&                  |      dz  }t)        t#        j*                  |            d
x}}\ y
y
# 1 sw Y   nxY w)z[Story 10.7: from_history() returns same BudgetRecommendation type as fifty_thirty_twenty().r   )BudgetRecommendation)from_history	Groceries)r/  r   F   r   r   appr.  Nz5assert %(py4)s
{%(py4)s = %(py0)s(%(py1)s, %(py2)s)
}r   recr2  )rB   rf   rC   rD   z[assert %(py6)s
{%(py6)s = %(py0)s(%(py3)s
{%(py3)s = %(py1)s.suggested_amount
}, %(py4)s)
}r   )rB   rf   rg   rD   rE   )(app.services.insights.budget_recommenderr2  'app.services.analytics.budget_analyticsr3  r   r   r0   hasattrr6  r   r   r   no_autoflushr   r   rO   rP   rM   rQ   rR   rS   rT   suggested_amount)rV   r   r2  r3  r+   r   r-   recsr7  rX   r   rp   rY   r   s                 r   9test_from_history_follows_budget_recommendation_interfacezYTestHistoryBasedRecommendations.test_from_history_follows_budget_recommendation_interface
  s   QH[)$ 	>HdCH=	> &-R%7RVV!S[[=U=U 	4	 23D	4 A!#';<<<<<<<<z<<<z<<<<<<#<<<#<<<<<<';<<<';<<<<<<<<<<"%"6"6@z"6@@@@@@@@z@@@z@@@@@@#@@@#@@@"6@@@@@@@@@@@@@@@@@@@A 	4 	4s   8K66L N)r   r   r   r  r!  r,  r0  r>  r   r   r   r  r     s    KRY
+Ar   r  )r4  )r   Shopr   F)r.  )%__doc__builtinsrO   _pytest.assertion.rewrite	assertionrewriterM   decimalr   datetimer   r   pytestapp.extensionsr   r   app.models.accountr   app.models.categoryr   app.models.transactionr	   app.models.budgetr
   app.models.settingsr   r   r   r0   r7   r9   r   r   r   r   r   r  r   r   r   <module>rN     s    3     $  $ & ( . $ (
	5 5." "H@ @")+ )+\+ +H. .<%A %Ar   