
    P1iaK                         d Z ddlmZmZ ddlmZ ddlmZmZ ddl	m
Z
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  G d de      Z G d de      Zy)u  
Unit tests for tongshu views YBP (Yellow/Black Path) functionality.

These tests verify that the tongshu calendar views correctly classify 
Yellow/Black Path gods as either good (黄道) or bad (黑道).

Good gods (黄道): 青龙, 明堂, 金匮, 天德, 玉堂, 司命
Bad gods (黑道): 天刑, 朱雀, 白虎, 天牢, 玄武, 勾陈

Tests cover:
- transform_day_data function classification
- get_day_data function classification  
- month_view response data
- specific known date classifications
- consistency across different calculation methods
- all 12 gods have correct classification

Usage:
    python manage.py test tongshu.tests.TongshuYBPViewsTestCase
    python manage.py test_ybp_views  # custom management command
    )TestCaseClient)reverse)datetime)transform_day_dataget_day_data)TongshuCalendar)bz)test_safe_print)get_user_model)Personc                   :    e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
y	)
TongshuYBPViewsTestCasezFTest cases for YBP (Yellow/Black Path) functionality in tongshu views.c                     t               | _        g d| _        g d| _        | j                  | j                  z   | _        g d| _        y)zSet up test fixtures.)u   青龙u   明堂   金匮u   天德   玉堂u   司命)u   天刑   朱雀u   白虎u   天牢u   玄武u   勾陈))     r   )r   r      )r   r      )r         )r         )r         )r   	   
   N)r   client	good_godsbad_godsall_gods
test_dates)selfs    //home/cursorai/projects/iching/tongshu/tests.pysetUpzTongshuYBPViewsTestCase.setUp%   s9    h VT6
    c           
         t        j                  dd      }|d   dd }d}d}|D ]%  }t        |dd      }| j                  d|       |d   }| j                  d|       | j                  d	|       | j                  d
|       |d   }| j                  || j                  d|        |d	   }	| j                  |	ddgd|	        || j
                  v r | j                  |	dd| d|	 d       |dz  }n-|| j                  v r| j                  |	dd| d|	 d       |dz  }|d
   }
| j                  |
dd       | j                  |
dd       ( | j                  |dd       | j                  |dd       t        d| d| d       y)zJTest that transform_day_data correctly classifies YBP gods as good or bad.r   r      Nr   r   yellow_black_pathgodtypepositionUnknown YBP god: goodbadInvalid YBP type: 	Good god & should be classified as 'good', got ''Bad god % should be classified as 'bad', got 'zYBP position should be >= 1r   zYBP position should be <= 12(Should have tested at least one good god'Should have tested at least one bad god   ✅ Tested  good gods and z bad gods in transform_day_data)r
   get_month_datar   assertInr$   r"   assertEqualr#   assertGreaterEqualassertLessEqualassertGreaterr   )r&   calendar_datasample_days
good_count	bad_count	day_arraytransformedybp_datagod_nameybp_typer/   s              r'   *test_transform_day_data_ybp_classificationzBTongshuYBPViewsTestCase.test_transform_day_data_ybp_classification9   s    (66tQ?#A&s+
	$I,Ya@K MM-{;"#67HMM%*MM&(+MM*h/  HMM(DMM5Fxj3QR  'HMM(VUO7I(5TU 4>>)  6z)OPXzYZ[]a
T]]*  5xj(MhZWXY[Q	  
+H##Ha1NO  2/MNC %H 	:q*TU9a)RS+j\Kjklr)   c                    d}d}| j                   D ]  \  }}}t        |||      }t        |      }| j                  d|       |d   }| j                  d|       | j                  d|       | j                  d|       |d   }	| j                  |	| j                  d|	        |d   }
| j                  |
ddgd	|
        |	| j
                  v r"| j                  |
dd
|	 d|
 d|        |dz  }|	| j                  v s| j                  |
dd|	 d|
 d|        |dz  } | j                  |dd       | j                  |dd       t        d| d| d       y)zDTest that get_day_data correctly classifies YBP gods as good or bad.r   r,   r-   r.   r/   r0   r1   r2   r3   r4   r5   z' for r   r7   r8   r9   r:   r;   r<   z bad gods in get_day_dataN)
r%   r   r	   r>   r$   r"   r?   r#   rB   r   )r&   rE   rF   yearmonthdaydate_objday_datarI   rJ   rK   s              r'   $test_get_day_data_ybp_classificationz<TongshuYBPViewsTestCase.test_get_day_data_ybp_classificationl   s    
	 $D%D%-H#H-H MM-x8 34HMM%*MM&(+MM*h/  HMM(DMM5Fxj3QR  'HMM(VUO7I(5TU 4>>)  6z)OPXzY_`h_ijla
T]]*  5xj(MhZW]^f]ghjQ	9 !0> 	:q*TU9a)RS+j\Kdefr)   c           	         t        dddd      }| j                  j                  |      }| j                  |j                  d       | j                  d|j                         |j                  d   }| j                  t        |      dd	       d}d}d}|D ]  }|D ]  }|dz  }| j                  d
|       |d
   }	| j                  d|	       | j                  d|	       | j                  d|	       |	d   }
|	d   }| j                  |
| j                  d|
        | j                  |ddgd|        |dk(  r'|dz  }| j                  |
| j                  d|
 d       |dk(  s|dz  }| j                  |
| j                  d|
 d         | j                  |dd       | j                  |dd       | j                  |dd       t        d| d| d| d       y)zHTest that the month view response contains properly classified YBP data.tongshu:month_viewr   r   rN   rO   kwargs   weeksr   zShould have at least one weekr,   r-   r.   r/   r0   r1   r2   r3   zGod z/ classified as 'good' but not in good_gods listz- classified as 'bad' but not in bad_gods list   z#Should have tested at least 30 daysz!Should have at least one good dayz Should have at least one bad dayu   ✅ Month view: Tested z days with z
 good and z bad classificationsN)r   r!   getr?   status_coder>   contextrB   lenr$   r"   r#   r   )r&   urlresponserZ   rE   rF   
total_daysweekrP   rI   rJ   rK   s               r'   *test_month_view_response_contains_ybp_datazBTongshuYBPViewsTestCase.test_month_view_response_contains_ybp_data   s    *D13MN;;??3'--s3gx//0  )3u:q*IJ
	
Da
 13723eX.fh/j(3 $E?#F+h9J8*7UVh;MhZ9XY v%!OJMM(DNNxj(WXZ&NIMM(DMMxj(UVX3  < 	:r+PQ:q*MN9a)KL1*[T^_h^ii}~r)   c                 v   t        ddd      ddft        ddd      ddft        ddd      ddft        ddd	      d
dfg}|D ]  \  }}}| j                  |||      5  t        |      }|d   }| j                  |d   |d| d| d|d           | j                  |d   |d| d| d| d|d           t	        j
                  |j                  |j                  |j                        }| j                  |       | j                  |d   |       | j                  |d   |       ddd        y# 1 sw Y   xY w)z3Test specific dates with known YBP classifications.r   r   r   r1   r   r   r   r   r   r   r2   )r   expected_godexpected_typer,   r-   z	Expected z for z, got r.   z on N)
r   subTestr	   r?   r   calcYellowBlackPathrN   rO   rP   assertIsNotNone)r&   known_cases	test_daterf   rg   rR   rI   calc_results           r'   'test_specific_known_ybp_classificationsz?TongshuYBPViewsTestCase.test_specific_known_ybp_classifications   sp   
 $1x0$1x0$1x0$B51	
 7B2I|]9<Wde'	2#$78  %,~U9+VHUOCTUW  &!1=eL>i[PVW_`fWgVhik !44Y^^Y__V_VcVcd$$[1  U!3\B  V!4mD fe 7Bees   CD//D8	c           	         t        ddd      }t        j                  |j                  |j                  |j
                        }t        |      }|d   }t        j                  |j                  |j                        }d}|j                  d      }|d   D ]  }|d   |k(  s|} n | j                  |d	| d
       t        ||j                  |j                        }	|	d   }
| j                  |d   |d   d       | j                  |d   |d   d       | j                  |d   |
d   d       | j                  |d   |
d   d       t        d| d|d    d|d    d       y)zETest that YBP calculations are consistent across different functions.r   r   r   r,   Nz%Y-%m-%dr+   r   zCould not find z in calendar datar-   z;Direct calculation and view function should return same godr.   z<Direct calculation and view function should return same typez;View function and transform function should return same godz<View function and transform function should return same typeu    ✅ Consistency test passed for z: z ())r   r   ri   rN   rO   rP   r	   r
   r=   strftimerj   r   r?   r   )r&   rl   rm   rR   view_ybprC   
target_daydate_strrG   rH   transform_ybps              r'   %test_ybp_consistency_across_functionsz=TongshuYBPViewsTestCase.test_ybp_consistency_across_functions   s    q"%	 ,,Y^^Y__imm\  	*/0 (66y~~yW 
%%j1&q)I|x'&
 *
 	Z?8*DU)VW(Y^^Y__U#$78 	U+Xe_I	KV,hv.>J	L 	%-*>I	K&)=+@J	L 	:9+RTYHZG[[]^ijp^q]rrstur)   c                    t               }i }t        dd      D cg c]  }d|f }}|D ]~  \  }}t        j                  ||      }|d   D ][  }t	        |||      }|d   }	|	d   }
|	d   }|j                  |
       |
|vr|||
<   :| j                  ||
   |d|
 d	||
    d
|        ]  | j                  t        |      ddt        |              |j                         D ]l  \  }
}|
| j                  v r| j                  |dd|
 d| d       /|
| j                  v r| j                  |dd|
 d| d       X| j                  d|
 d       n t        |D cg c]  }|| j                  v s| c}      }t        |D cg c]  }|| j                  v s| c}      }t        dt        |       d| d| d       t        dt        |D cg c]  }|| j                  v s| c}              t        dt        |D cg c]  }|| j                  v s| c}              yc c}w c c}w c c}w c c}w c c}w )zKTest that all 12 YBP gods have the correct classification when they appear.r      r   r+   r,   r-   r.   z Inconsistent classification for z: saw both z and    z6Should have seen at least 8 different gods, only saw: r1   r4   z was classified as 'r6   r2   r7   zUnknown god z encounteredr;   z different gods: z good, z badz   Good gods seen: z   Bad gods seen: N)setranger
   r=   r   addr?   r@   r_   sorteditemsr"   r#   failr   )r&   	gods_seenclassifications_testedrO   test_monthsrN   rC   rG   rH   rI   rJ   rK   observed_typeg	good_seenbad_seens                   r'   0test_all_twelve_gods_have_correct_classificationzHTongshuYBPViewsTestCase.test_all_twelve_gods_have_correct_classification  s    E	!# 382,?,e},?&KD%+::4GM*1-	0D%H&':;#E?#F+h' #997?*84 $$%;H%Ex:8*KPfgoPpOqqvw  wA  BC . '* 	IDVIEVDWX	Z (>'C'C'E#Hm4>>)  z)=m_ANPT]]*  xj(<]O1MO 		L
,?@ (F IEIqdnn1DIEF	9C9aT]]0B9CD+c)n%55FykQXYaXbbfgh-f5bAaSWSaSaNaa5b.c-def,V	4`	1QRVR_R_M_Q	4`-a,bcdU @J FC 6c4`s5   H)H./H.H3H3H8#H8H=H=N)__name__
__module____qualname____doc__r(   rL   rS   rd   rn   rv   r    r)   r'   r   r   "   s2    P
(1mf(gT3@jE8'vR2er)   r   c                   6    e Zd ZdZd Zd	dZd Zd Zd Zd Z	y)
TongshuUserBaZiHeaderTestszSTests for the UI header that shows the logged-in user's BaZi in tongshu month view.c                 ~    t               | _        t               }|j                  j	                  dddd      | _        y )N10000000001p1zu1@example.comU1)phonepasswordemail
first_name)r   r!   r   objectscreate_useruser)r&   Users     r'   r(   z TongshuUserBaZiHeaderTests.setUpH  s4    hLL,,=4Wgtx,y	r)   c                     dddddddddd}|rd	d
d|d<   t        dt        dd
d      t        dd      | j                  d|      }d|_        |j                          |S )N   r   )r-   earthr+   r   r   ry   )rP   rO   rN   r   r   hourTesteri        r[   T)name
birth_date
birth_time
created_byownerbazi_result)r   r   r   r   _skip_bazi_calculationsave)r&   has_hourr   ps       r'   _create_owner_personz/TongshuUserBaZiHeaderTests._create_owner_personM  s~     q)+*

 *+a"8KD!R(B|yy#
 $( 	r)   c                     |j                  d      }| j                  |dd       d}|j                  ||      }|dk(  r|dz   }||| S )N   我的八字u&   Header label 我的八字 should existz<!-- Year dropdowni   )findassertNotEqual)r&   response_textstart
end_anchorends        r'   _get_header_htmlz+TongshuUserBaZiHeaderTests._get_header_htmld  sY    "">2E2'OP)
  U3"9#+CU3''r)   c                    | j                  d       | j                  j                  | j                         t	        dddd      }| j                  j                  |      }| j                  |j                  d       |j                  j                  d	      }| j                  d
|       | j                  d|       | j                  |      }| j                  d|       t        j                  d   }t        j                  d   }t        j                  d   }t        j                  d   }|j                  |      }	|j                  |      }
|j                  |      }|j                  |      }| j                  |	dk7  xr |
dk7  xr |dk7  xr |dk7  d       | j                  |	|
cxk  xr |cxk  xr |k  nc d       | j!                  d|       | j!                  d|       y )NTr   rU     ry   rV   rW   rY   utf-8r   zcss/bazi.csszelement-firer   r   r+   r   r   z:All four pillar god characters should be present in headerz3Pillars should be ordered Hour < Day < Month < Yearz
1981-01-11z22:30)r   r!   force_loginr   r   r\   r?   r]   contentdecoder>   r   r   gGodstemr   
assertTrueassertNotIn)r&   r`   ra   htmlheader	hour_charday_char
month_char	year_charidx_houridx_day	idx_monthidx_years                r'   )test_header_shows_label_pillars_and_colorzDTongshuUserBaZiHeaderTests.test_header_shows_label_pillars_and_coloro  s   !!4!0		**D13MN;;??3'--s3&&w/nd+nd+&&t,nf-KKN	;;q>[[^
KKN	;;y)++h'KK
+	;;y)B_7b=_Y"__QY]_Q_T	V7AYAAM	O 	t,$'r)   c                    | j                  d       | j                  j                  | j                         t	        dddd      }| j                  j                  |      }| j                  |j                  d       |j                  j                  d	      }| j                  |      }t        j                  d
   }t        j                  d   }t        j                  d   }|j                  |      }|j                  |      }	|j                  |      }
| j                  |dk7  xr |	dk7  xr |
dk7         | j                  ||	cxk  xr |
k  d       y c d       y )NFr   rU   r   ry   rV   rW   rY   r   r   r+   r   r   z0Without hour, order should be Day < Month < Year)r   r!   r   r   r   r\   r?   r]   r   r   r   r   r   r   r   )r&   r`   ra   r   r   r   r   r   r   r   r   s              r'   6test_header_without_hour_shows_three_pillars_day_firstzQTongshuUserBaZiHeaderTests.test_header_without_hour_shows_three_pillars_day_first  s$   !!5!1		**D13MN;;??3'--s3&&w/&&t,;;q>[[^
KKN	++h'KK
+	;;y)2L)r/Lh"nM)6h6J	L6J	Lr)   c                     | j                   j                  | j                         t        dddd      }| j                   j	                  |      }|j
                  j                  d      }| j                  d|       y )NrU   r   ry   rV   rW   r   r   )r!   r   r   r   r\   r   r   r   )r&   r`   ra   r   s       r'   $test_header_not_shown_when_no_personz?TongshuUserBaZiHeaderTests.test_header_not_shown_when_no_person  sb    		**D13MN;;??3'&&w/.r)   N)T)
r   r   r   r   r(   r   r   r   r   r   r   r)   r'   r   r   E  s%    ]z
.	((<L&/r)   r   N)r   django.testr   r   django.urlsr   datetimer   r   tongshu.viewsr   r	   tongshu.modelsr
   iching.utilsr   iching.utils.utilsr   django.contrib.authr   bazi.modelsr   r   r   r   r)   r'   <module>r      sF   , )   : *  . . `eh `eF	`/ `/r)   