
    P1i                        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	m
Z
 d dlZd dlmZ d dlmZmZmZmZmZmZ  G d	 d
e      Zy)    )annotations)TestCase)get_user_model)reverse)datetimeN)Person)	REL_LIUHEREL_BANSANHEREL_TIANGANHE	REL_CHONGREL_HAIREL_XINGc                  v    e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zd Zd Zd Zd Zd Zd Zd Zy)APIResponseStructureTestszJTest API response structures for proper t=r/s mapping and index alignment.c           	     h   t               }|j                  j                  ddd      | _        | j                  j                  | j                         t        j                  j                  ddt        ddd      t        d	d
      | j                  d      | _
        | j                  j                          | j                  j                          | j                  j                  j                  di       }|r0t        d|j                  d       d|j                  d              y t        d       y )N13900000000xztest@example.com)phonepasswordemailOwnerM     
   r   T)namegender
birth_date
birth_time
created_byownerdayzOwner day pillar: God=god_idxz, Earth=	earth_idxz1Warning: Owner day pillar not calculated properly)r   objectscreate_useruserclientforce_loginr	   creater   r   r"   calculate_bazisavebazi_resultgetprint)selfUser
day_pillars      G/home/cursorai/projects/iching/api/tests/test_api_response_structure.pysetUpzAPIResponseStructureTests.setUp   s    LL,,#5G - 
	 			* ^^**dAq1AB{tyy + 


 	

!!#

 ZZ++//r:
*:>>)+D*EXjnn]hNiMjklEF    c                   t        d      }| j                  j                  |      }| j                  |j                  d       |j                         }d|v rE| j                  |d   g d       |d   dk(  r%| j                  d|       | j                  d|       yy| j                  d|       | j                  d|       y)	z4Test that the with-relations endpoint is accessible.api:bazi-with-relations   status)
processingreadyerrorr<   resultscountN)r   r)   r/   assertEqualstatus_codejsonassertInr1   urlrespdatas       r4   #test_with_relations_endpoint_existsz=APIResponseStructureTests.test_with_relations_endpoint_exists)   s    /0{{s#))3/yy{ tMM$x.*JKH~(i.gt, )
 MM)T*MM'4(r6   c           
        t         j                  j                  ddt        ddd      t	        dd      | j
                        }|j                          |j                          ddlm	}  |d	| j
                  j                  d
       t        d      }| j                  j                  |      }| j                  |j                  d       |j!                         }| j#                  d|       | j#                  d|       |d   dkD  rbd}|d   D ]  }|d   |j                  k(  s|} n |r#| j#                  d|       |d   }| j%                  |t&               |D 	cg c]  }	|	j                  d      dk(  s|	 }
}	t)        |
      dkD  r|
D ]  }| j                  |d   dd       | j#                  d|d       | j%                  |d   t*        d       | j#                  |d   t,        t.        t0        t2        t4        t6        gd|d           | j9                  d|d       | j#                  d|d        yt;        d|j                          yt;        d|j                   d        yt;        d!       yc c}	w )"zBTest that relation type 'r' uses 'c' field for relationship codes.TestPerson1F  r      r   r   r   r   r    r!   call_commandrecalc_bazi_relationsTr(   forcer8   r9   r>   r?   Nidrelation_goodtrzRelation type must be 'r'cz!Relation reason missing 'c' fieldzRelation code must be integerzInvalid relation code: iz)Relation reason should not have 'i' fieldby"Relation reason missing 'by' fieldz*No relation type reasons found for person Person $ not found in with-relations results+No results found in with-relations endpoint)r	   r&   r+   r   r   r(   r,   r-   django.core.managementrP   rT   r   r)   r/   r@   rA   rB   rC   assertIsInstancelistlenintr
   r   r   r   r   r   assertNotInr0   )r1   personrP   rE   rF   rG   person_dataresultrU   rW   relation_reasonsreasons               r4   !test_relation_type_r_uses_c_fieldz;APIResponseStructureTests.test_relation_type_r_uses_c_field<   sM    &&stD!R7HB{tyy ' 
 	 	8,499<<tL /0{{s#))3/yy{ 	i&gt$ =1Ky/$<699,"(K *
 o{; +O <%%mT: 0=#R}!c
c@QA} #R'(1,"2((c;VW c63VW--fSk3@_` fSkI|]2;Wh4P'>vc{m%LN
 ((f6ab dF4XY# #3( FvyykRS 		{*NOP ?@; $Ss   I68I6c           	        t         j                  j                  ddt        ddd      t	        dd      | j
                        }|j                          |j                          ddlm	}  |d	| j
                  j                  d
       t        d      }| j                  j                  |      }| j                  |j                  d       |j!                         }| j#                  d|       | j#                  d|       |d   dkD  rd}|d   D ]  }|d   |j                  k(  s|} n |r|d   }|D 	cg c]  }	|	j                  d      dk(  s|	 }
}	t%        |
      dkD  rq|
D ]k  }| j                  |d   dd       | j#                  d|d       | j'                  |d   t(        d       | j+                  d|d       | j#                  d|d       m yt-        d|j                          yt-        d|j                   d       yyc c}	w ) z>Test that sha god type 's' uses 'i' field for sha god indices.TestPerson2r   rL   r      r   rN   rO   rQ   TrR   r8   r9   r>   r?   NrT   rU   rV   szSha god type must be 's'rY   z Sha god reason missing 'i' fieldzSha god index must be integerrX   z(Sha god reason should not have 'c' fieldrZ   z!Sha god reason missing 'by' fieldz)No sha god type reasons found for person r\   r]   )r	   r&   r+   r   r   r(   r,   r-   r_   rP   rT   r   r)   r/   r@   rA   rB   rC   rb   r`   rc   rd   r0   )r1   re   rP   rE   rF   rG   rf   rg   rU   rW   sha_god_reasonsri   s               r4    test_sha_god_type_s_uses_i_fieldz:APIResponseStructureTests.test_sha_god_type_s_uses_i_field   s   
 &&stD!R7HB{tyy ' 
 	 	8,499<<tL /0{{s#))3/yy{ 	i&gt$ =1Ky/$<699,"(K *
  +O < /<"QmquuSzS?P1m"Q'!+"1((c;UV c63UV--fSk3@_` ((f6`a dF4WX #2 Efii[QR 		{*NOPE  #Rs   4HHc           	     v   t         j                  j                  ddt        ddd      t	        dd      | j
                        }|j                          |j                          ddlm	}  |d	| j
                  j                  d
       t        d      }| j                  j                  |      }| j                  |j                  d       |j!                         }| j#                  d|       | j#                  d|       |d   dkD  r"d}|d   D ]  }|d   |j                  k(  s|} n |r|d   D cg c]0  }|j                  d      dk(  r|j                  d      t$        k(  r|2 }	}t'        |	      dkD  r|	D ]y  }
| j#                  d|
d       | j)                  |
d   t*        d       | j#                  |
d   t-        d      d|
d           | j#                  |
d   t-        d      d|
d           { yt/        d|j                          yt/        d|j                   d       yt/        d       yc c}w ) uI   Test that 天干合 (c=2) relations include '5e' field for five elements.TestPerson3rK   rL   r      r   rN   rO   rQ   TrR   r8   r9   r>   r?   NrT   rU   rV   rW   rX   5eu#   天干合 reason missing '5e' fieldzFive element must be integer   zInvalid five element: z Five element should be 0-4, got z&No tianganhe reasons found for person r\   r]   r^   )r	   r&   r+   r   r   r(   r,   r-   r_   rP   rT   r   r)   r/   r@   rA   rB   rC   r   rb   r`   rc   ranger0   )r1   re   rP   rE   rF   rG   rf   rg   rW   tianganhe_reasonsri   s              r4   test_tianganhe_has_5e_fieldz5APIResponseStructureTests.test_tianganhe_has_5e_field   s"    &&stD!R7HB{tyy ' 
 	 	8,499<<tL /0{{s#))3/yy{ 	i&gt$ =1Ky/$<699,"(K *
 0;O0L %Y0L1&'eeCjC&7AEE#J-<W &'0L! %Y ()A-"3dF4YZ--fTlCA_` fTlE!H@VW]^bWcVd>ef fTlE!H@`aghlam`n>op #4 B699+NO 		{*NOP ?@/%Ys   35H6c           	        t         j                  j                  ddt        ddd      t	        dd      | j
                        }|j                          |j                          ddlm	}  |d	| j
                  j                  d
       t        d      }| j                  j                  |      }| j                  |j                  d       |j!                         }| j#                  d|       | j#                  d|       |d   dkD  rd}|d   D ]  }|d   |j                  k(  s|} n |r|d   D cg c]0  }|j                  d      dk(  r|j                  d      t$        k7  r|2 }	}t'        |	      dkD  r|	D ]  }
| j)                  d|
d|
         yt+        d|j                          yt+        d|j                   d       yt+        d       yc c}w )u8   Test that non-天干合 relations don't have '5e' field.TestPerson4r   rL   r      r   rN   rO   rQ   TrR   r8   r9   r>   r?   NrT   rU   rV   rW   rX   rt   z-Non-tianganhe relation should not have '5e': z,No non-tianganhe relations found for person r\   r]   r^   )r	   r&   r+   r   r   r(   r,   r-   r_   rP   rT   r   r)   r/   r@   rA   rB   rC   r   rb   rd   r0   )r1   re   rP   rE   rF   rG   rf   rg   rW   non_tianganheri   s              r4   (test_non_tianganhe_relations_no_5e_fieldzBAPIResponseStructureTests.test_non_tianganhe_relations_no_5e_field	  s    &&stD!R7HB{tyy ' 
 	 	8,499<<tL /0{{s#))3/yy{ 	i&gt$ =1Ky/$<699,"(K *
 ,7,H !V,Hq#$55:#4s}9T "#,H !V }%)"/((v)VW]V^'_a #0 HTU 		{*NOP ?@!!Vs   25Gc                    t         t        t        t        t        t
        d}|j                         D ]  \  }}| j                  ||d|         y)z6Test that relation codes match the documented mapping.)r   r            ru   z(Relation code mapping mismatch for code N)r
   r   r   r   r   r   itemsr@   )r1   expected_codesexpected_codeconstant_values       r4   test_relation_codes_mappingz5APIResponseStructureTests.test_relation_codes_mappingC  sU     
 .<-A-A-C)M>]NEm_UW .Dr6   c                    ddl m} dddd}|j                         D ]<  \  }}|j                  j	                  |      }| j                  ||d| d| d	|        > y
)z>Test that sha god indices align with bzshagod.py gShagodNames.r   )bzshagodu   天乙u   文昌u   桃花)r   ru      zSha god index z mismatch: expected z, got N)iching.utilsr   r   gShagodNamesr/   r@   )r1   sgexpected_indicesindexexpected_nameactual_names         r4   (test_sha_god_indices_align_with_bzshagodzBAPIResponseStructureTests.test_sha_god_indices_align_with_bzshagodR  ss    / 
 %5$:$:$< E=//--e4K[-+E72F}oU[\g[hik %=r6   c                   t        d      }| j                  j                  |      }| j                  |j                  d       |j                         }| j                  d|       | j                  d|       d|v r+| j                  |d   du xs t        |d   t                     d|v r+| j                  |d   du xs t        |d   t                     | j                  |d   t               y)z5Test that paginated responses have correct structure.r8   r9   r?   r>   nextNprevious)r   r)   r/   r@   rA   rB   rC   
assertTrue
isinstancestrr`   ra   rD   s       r4   &test_api_response_pagination_structurez@APIResponseStructureTests.test_api_response_pagination_structureb  s    /0{{s#))3/yy{ 	gt$i& T>OODLD0QJtF|S4QROOD,4Y
4
CSUX8YZ 	d9ot4r6   c           	        t         j                  j                  ddt        ddd      t	        dd      | j
                        }|j                          |j                          ddlm	}  |d	| j
                  j                  d
       t        d      }| j                  j                  |      }|j                         }t        |d         dkD  r|d   d   }g d}|D ]  }| j!                  ||d|         | j!                  d|d   d       ddg}	|	D ]  }| j!                  ||d|         | j#                  |d   t$               | j#                  |d   t$               | j'                  d|d       | j'                  d|d       yy)zBTest that person records in API responses have complete structure.StructureTestrK   i        r   rN   rO   rQ   TrR   r8   r>   )rT   r   r   r   rg   zMissing required field: r.   rg   z#Missing bazi_result in result fieldrU   relation_badzMissing relation field: relation_good_countz0Count fields should be omitted from API responserelation_bad_countN)r	   r&   r+   r   r   r(   r,   r-   r_   rP   rT   r   r)   r/   rB   rb   rC   r`   ra   rd   )
r1   re   rP   rE   rF   rG   person_recordrequired_fieldsfieldrelation_fieldss
             r4   %test_complete_person_record_structurez?APIResponseStructureTests.test_complete_person_record_structurev  s    && dAq9IB{tyy ' 
 	 	8,499<<tL/0{{s#yy{tI!# OA.M OO(e]6Nug4VW ) MM-x)@Bgh  /?O(e]6Nug4VW ) !!-"@$G!!-"?F 2MMO1=MO/ $r6   c           
     @   t         j                  j                  ddt        ddd      t	        dd      | j
                        }d|_        dd	d
ddd
d	dd
ddd
d|_        |j                  dg       ddl	m
}  |d| j
                  j                  d       t        d      }| j                  j                  |      }|j                         }d}|d   D ]  }|d   |j                  k(  s|} n |r)|d   |d   z   }|D ]  }	| j!                  d|	d       |	d   }
| j#                  |
t$        d       | j'                  t)        |
      dd       |
D ]  }| j#                  |t$        d       | j'                  t)        |      dd        |\  }}}}| j!                  |d!d"gd#|        | j!                  |g d$d%|        | j!                  |d&d'gd(|        | j#                  |t*        d)       | j!                  |t-        |d'k(  rd*nd+      d,| d-|          yy).zFTest that 'by' field has correct structure for relationship breakdown.ByFieldTestr   i  r      r   rN   Tru   godearthr   r   r   yearmonthr#   hourr.   update_fieldsrO   rQ   rR   api:bazi-person-relationsNr>   rT   rU   r   rZ   r[   z'by' field must be a listz.'by' field should have 2 elements for pairwisezBreakdown must be a listr   zBreakdown must have 4 elementsopzInvalid 'who' value: )ymdhzInvalid pillar: gezInvalid bazi type: zValue must be integerrm   r   zInvalid value for z: )r	   r&   r+   r   r   r(   _skip_bazi_calculationr.   r-   r_   rP   rT   r   r)   r/   rB   rC   r`   ra   r@   rb   rc   rv   )r1   re   rP   rE   rF   rG   rf   rg   all_relationsri   by_field	breakdownwhopillar	bazi_typevalues                   r4   test_by_field_structurez1APIResponseStructureTests.test_by_field_structure  s:    &&stD!Q7GB{tyy ' 
 )-%*+q)*	
 	=/2 	8,499<<tL12{{s#yy{ 9oFd|vyy($ &
 '8;~;VVM'dF,PQ!$< %%h6QR   X3cd "*I)))T;UV$$S^Q8XY4=1CEMM#Sz5J3%3PQMM&*>BRSYRZ@[\MM)c3Z;Nyk9Z[))%6MNMM%Y#5Er2)N"4YKr% IK "* ( r6   c           	        t         j                  j                  ddt        ddd      t	        dd      | j
                        }d|_        d	d
ddddddddddd|_        |j                  dg       ddl	m
}  |d| j
                  j                  d       t        d      }| j                  j                  |      }|j                         }|d   D cg c]  }|d   	 }}| j!                  |j                  |d       yc c}w )z4Test API structure when person has no relationships.NoRelationsrK   i        r   rN   Tr   rM   r   r   r   	   r   r   r   r.   r   rO   rQ   rR   r   r>   rT   zGPerson with no relations should not appear in person-relations endpointN)r	   r&   r+   r   r   r(   r   r.   r-   r_   rP   rT   r   r)   r/   rB   rd   )r1   re   rP   rE   rF   rG   rg   
person_idss           r4   test_empty_relations_structurez8APIResponseStructureTests.test_empty_relations_structure  s    &&stD!Q7GB{tyy ' 
 )-%+,q)*	
 	=/2 	8,499<<tL 12{{s#yy{ 26iAvfTl
AJa	c Bs   Dc                   t         j                  j                  ddt        ddd      t	        dd      | j
                        }|j                          |j                          t        d	d
|j                  i      }| j                  j                  |      }| j                  |j                  dd|j                          |j                         }g d}|D ]  }| j                  ||d|         | j                  d|d       |d   }g d}|D ]  }	| j                  |	|d|	        ||	   }
| j!                  |
d|	 d       |
s8g d}|D ]  }| j                  ||
d| d|	 d        g d}|D ]  }| j!                  |
|   d|	 d| d         | j#                  |
d   t$        d|	 d        | j#                  |
d!   t$        d"|	 d        | j#                  |
d#   t&        d$|	 d%       | j#                  |
d&   t&        d'|	 d%       | j#                  |
d(   t(        d)|	 d*       | j+                  |
d   d+d|	 d,       | j+                  |
d!   d+d"|	 d,       |
d-   sU|
d-   D ](  }| j                  d|d.       | j                  d/|d0       *  | j                  d1|d2       |d1   }| j!                  |d3       |r|D ]  }	|	|v s||	   }| j                  d4|d5|	 d6       |d4   }| j#                  |t,        d7|	 d8       |D ]Z  }| j                  d9|d:       | j                  d;|d<       | j#                  |d;   t&        d=       | j                  |d;   g d>d?       \  | j                  d@|dA       |d@   }| j!                  |dB       |r| j#                  |t,        dC       |D ]  }g dD}|D ]  }| j                  ||dE| dF        | j#                  |dG   t&        dH       | j#                  |d   t$        dI       | j#                  |dJ   t,        dK       | j#                  |dL   t,        dM       | j#                  |dN   t,        dO       | j#                  |dP   t&        dQ        g dR}|D ]  }| j                  ||dS|         |dT   }| j!                  |dU       |r{|D ]v  }	|	|v s||	   }
| j                  d|
dV|	 dW       | j                  d!|
dV|	 dX       | j#                  |
d   t&        dV|	 dY       | j#                  |
d!   t&        dV|	 dZ       x | j                  d[|d\       |d[   }| j!                  |d]       |r!g d^}|D ]  }| j                  ||d_|         | j                  d`|da       | j                  db|dc       | j#                  |d`   t,        dd       | j#                  |db   t,        de       yf)gzJTest that the individual BaZi GET API returns complete response structure.BaZiAPITestr   rL   r   rM         rN   api:bazi-detailpkkwargsr9   zAPI should return 200, got )rT   r   r   r   r    	twin_type
father_dob
mother_dobnotes
created_at
updated_atr!   zMissing basic field: rg   zMissing 'result' fieldr   zMissing pillar: Pillar z should not be null)r   r   earth_elementten_godhidden_godsemptyr$   r%   god_elementstar_luck_idxself_luck_idxzMissing field 'z' in  pillarr   r   r$   r%   
CRITICAL: .5 must not be null - this was causing the recent issuer   zGod in z should be stringr   z	Earth in r$   zGod index in z should be intr%   zEarth index in r   z	Empty in z should be bool z should not be empty stringr   zHidden god missing 'god' fieldr   z"Hidden god missing 'ten_god' fieldsha_godszMissing 'sha_gods' fieldzsha_gods should not be nullgodszMissing 'gods' in sha_gods[]zgods in sha_gods[z] should be listr   zSha god missing 'name' fieldkindnessz Sha god missing 'kindness' fieldzSha god kindness should be int)r   r   r   z%Sha god kindness should be 0, 1, or 2sha_god_locationsz!Missing 'sha_god_locations' fieldz$sha_god_locations should not be nullz sha_god_locations should be list)gidr   locger   upczSha god location missing 'z' fieldr   zgid should be intzgod should be stringr   zloc should be listr   zge should be listr   zpillar should be listr   zupc should be int)	life_numberlife_palaceten_year_fate	year_fatecurrent_yearcurrent_10yearr.   nominal_ageelement_strengthszMissing field: r.   zbazi_result should not be nullbazi_result[z] missing 'god' fieldz] missing 'earth' fieldz].god should be intz].earth should be intnumberzMissing 'number' fieldznumber should not be null)headno_nosr   zodiacformulaliunianmingpanpairs81year_5ehave_nosyear_5ecyear_5elyear_5es	number_5e
number_5ec
number_5el
number_5esyear_numberzodiac_boostzMissing number field: rU   zMissing 'relation_good' fieldr   zMissing 'relation_bad' fieldzrelation_good should be listzrelation_bad should be listN)r	   r&   r+   r   r   r(   r,   r-   r   rT   r)   r/   r@   rA   rB   rC   assertIsNotNoner`   r   rc   boolassertNotEqualra   )r1   re   rE   rF   rG   basic_fieldsr   rg   pillarsr   pillar_datapillar_fieldscritical_fields
hidden_godr   
pillar_shar   r   sha_locationslocationr   other_fieldsr.   r   number_fieldss                            r4   $test_bazi_get_api_response_structurez>APIResponseStructureTests.test_bazi_get_api_response_structure  s`    &&stD!R7HB|		 ' 
 	 'vyy0AB{{s#))32MdN^N^M_0`ayy{f!EMM%)>ug'FG " 	h&>?h 3FMM&&,<VH*EF .K  x?R.ST!q*EMM%weTZS[[b6cd + #K,E((#E*$VHAeW4ij - %%k%&8#Pa?bc%%k'&:C9VHTeAfg%%k)&<c]SYRZZhCij%%k+&>W]V^^lEmn%%k'&:DIfXUdBef ##K$6gfXMh<ij##K$8"	&Ql>mn }-&1-&@
eZ9YZi=ab 'AC L 	j&*DE*%X'DE!X%!)&!1JMM&*8STZS[[\6]^%f-D))$8I&Qa6bc#fc3QRj#7YZ--c*osDdec*oyBij	  $ " 	)63VW23],RS!!-7YZ)"N,EMM%5OPUwV]3^_ - %%huos<OP%%huos<RS%%huot=QR%%htnd<OP%%hx&8$@WX%%huos<OP *l!EMM%?5')BC "
 ]+[*JK![("-f"5KMM%VHLa6bcMM';,vhNe8fg))+e*<c\RXQYYlCmn))+g*>|TZS[[pEqr " 	h&>?hV%@AqM 'eV/EeW-MN ' 	ot-LMnd,JKd?3T;YZd>2D:WXr6   c           
        t         j                  j                  ddt        ddd      t	        dd      | j
                        }|j                          |j                          t        d	d
|j                  i      }| j                  j                  |      }| j                  |j                  d       |j                         }t        ddd      |_        |j                          | j                  j                  |      }| j                  |j                  d       |j                         }|d   }dD ]  }| j!                  ||   d| d       ||   s"| j#                  d||   d| d       | j#                  d||   d| d       g d}	|	D ]!  }
| j!                  ||   |
   d| d|
 d       # | j%                  ||   d   dd| d       | j%                  ||   d   dd| d        | j!                  |d    d!       | j!                  |d"   d#       | j!                  |d$   d%       |d$   rdD ]  }| j#                  ||d$   d&| d'       |d$   |   }| j!                  |d&| d(       |s>| j#                  d|d&| d)       | j#                  d|d&| d*       | j!                  |d   d&| d+       | j!                  |d   d&| d,        | j%                  |d-   |d-   d.       y/)0zETest that BaZi GET API returns complete response after record update.
UpdateTestrK   r   ru   r   r{   r   rN   r   r   r   r9     r      rg   r   r   z$ should be recalculated after updater   zUpdated z pillar missing 'god' fieldr   z pillar missing 'earth' fieldr   zCRITICAL: Updated r   r   r   z.god should not be empty stringz!.earth should not be empty stringr   z,sha_gods should be recalculated after updater   z5sha_god_locations should be recalculated after updater.   z)bazi_result must not be null after updater   ] missing after updatez] must not be null after update].god missing after update].earth missing after updatez#].god must not be null after updatez%].earth must not be null after updater   z%Birth date should change after updateN)r	   r&   r+   r   r   r(   r,   r-   r   rT   r)   r/   r@   rA   rB   r   r  rC   r  )r1   re   rE   initial_respinitial_dataupdated_respupdated_datarg   r   r  r   r  s               r4   test_bazi_get_api_after_updatez8APIResponseStructureTests.test_bazi_get_api_after_update  s3    &&cd4B6GB|		 ' 
 	 'vyy0AB{{s+1137#((* !q"- {{s+1137#((* h' 7F  76(Bf1ghf~eVF^xxGb5cdgvf~&If7gh #K,E((vu-,VHAeW<qr - ##F6N5$92&Qp?qr##F6N7$;R8F8StAuv! 7& 	VJ/1_` 	V$78:qr 	VM24_`- :ff]&;|F8Si=jk$]3F;$$[LHg2hiMM%VHLf6ghMM';,vhNj8kl((U);|F8Sv=wx((W)=fXUz?{| ; 	L6\8RB	Dr6   c           	     b   t         j                  j                  ddt        ddd      d| j                        }|j                          |j                          t        dd	|j                  i
      }| j                  j                  |      }| j                  |j                  d       |j                         }|d   }g d}|D ]  }| j                  ||d| d        |d   	 | j                  |d   d       |d   r/| j                  d|d   d       | j                  |d   d   d       yy)z4Test that BaZi GET API properly handles null fields.NullTestNi  rm      NrN   r   r   r   r9   rg   )r   r   r#   r   r   r   r   r   r   r   r   r   r.   r   r   zRequired field 'z' missing from resultr   r.   z&bazi_result should always be populatedr#   z)bazi_result should always have day pillarz,Day pillar in bazi_result should not be null)r	   r&   r+   r   r(   r,   r-   r   rT   r)   r/   r@   rA   rB   rC   r  )r1   re   rE   rF   rG   rg   r   r   s           r4   &test_bazi_get_api_null_fields_handlingz@APIResponseStructureTests.test_bazi_get_api_null_fields_handling  s5    &&CDr24F		 ' 
 	 'vyy0AB{{s#))3/yy{ho %EMM%+;E7BW)XY % &>! 	VM24\]- MM%!68cd  !6u!=?mn !r6   c           
        t         j                  j                  ddt        ddd      t	        dd      | j
                        }|j                          |j                          t        dd	|j                  i
      }| j                  j                  |      }| j                  |j                  d       |j                         }|d   }g d}|D ]p  }| j                  ||   d| d       ||   s"g d}|D ]!  }	| j                  ||   |	   d| d|	 d       # 	dv sQ| j!                  ||   |	   dd| d|	 d       r | j                  |d   d       | j                  |d   d       | j                  |d   d       |d   r|D ]  }| j#                  ||d   d| d       |d   |   }
| j                  |
d| d        |
s>| j#                  d!|
d| d"       | j#                  d#|
d| d$       | j                  |
d!   d| d%       | j                  |
d#   d| d&        g d'}|D ]U  }	|	|v s||	   t%        ||	   t&        t(        f      r(t%        ||	   t*              s<| j!                  ||	   dd)|	 d*       W y()+zfTest that BaZi GET API returns NO NULL values for critical fields that were previously causing issues.
NoNullTestr   i  r   r   -   rN   r   r   r   r9   rg   r   zCRITICAL: Pillar z must not be nullr   r   r   r   r   r   z must not be empty stringr   z#CRITICAL: sha_gods must not be nullr   z,CRITICAL: sha_god_locations must not be nullr.   z&CRITICAL: bazi_result must not be nullz CRITICAL: bazi_result must have r   zCRITICAL: bazi_result[z] must not be nullr   z] must have 'god' fieldr   z] must have 'earth' fieldz].god must not be nullz].earth must not be null)r   r   r   NzField z& should not be empty string if present)r	   r&   r+   r   r   r(   r,   r-   r   rT   r)   r/   r@   rA   rB   r  r  rC   r   rc   floatr   )r1   re   rE   rF   rG   rg   critical_pillarsr   critical_pillar_fieldsr   r  important_fieldss               r4   0test_bazi_get_api_no_null_values_critical_fieldszJAPIResponseStructureTests.test_bazi_get_api_no_null_values_critical_fields  s    &&cd4B6GB|		 ' 
 	 'vyy0AB{{s#))3/yy{h <&F  3DVHL]1^_f~)Q&3E((vu-$VHAeW4ij 4 ,,''vu-$VHAeW4MN '* 	VJ/1VW 	V$78:hi 	VM24\]- *ff]&;?_`f_ggn=op$]3F;$$[4J6(Rd2ef MM%8NvhVm6noMM';:PQWPXXq8rs((U);?UV\U]]s=tu((W)=AWX^W__w?xy + I%E%=,!&-#u>#F5M37++F5M2wNt?uv &r6   c           
     J   t         j                  j                  ddt        ddd      t	        dd      | j
                        }|j                          |j                          t        d	d
|j                  i      }| j                  j                  |      }| j                  |j                  d       |j                         }i }|d   }dD ]3  }||   s	i ||<   ||   j                         D ]  \  }}	|		|	||   |<    5 t        ddd      |_        |j                          | j                  j                  |      }
| j                  |
j                  d       |
j                         }|d   }|j                         D ]  \  }}| j#                  ||   d| d       ||   s%|j                         D ]  \  }}||   j                  |      }| j#                  |d| d| d       t%        |t&        t(        f      sJt%        |t&        t(        f      sa|dk\  r| j+                  |d| d| d       |dk  s| j-                  |d| d| d         g d}|D ]  }| j#                  ||   d| d        |d   rdD ]  }| j/                  ||d   d| d       |d   |   }| j#                  |d| d        |s>| j/                  d!|d| d"       | j/                  d#|d| d$       | j#                  |d!   d| d%       | j#                  |d#   d| d&        yy)'zRTest that updating a BaZi record preserves all values and doesn't introduce nulls.UpdatePreserveTestrK   r   r   r   rm   r   rN   r   r   r   r9   rg   r   Nr  r   r   r   z became null after updater   r   z5 became null after update - this was the recent issuer   z should not become negativerM   z should not exceed valid range)r   r   r.   r.   r   r  z] became null after updater   r  r   r   z].god became null after updatez ].earth became null after update)r	   r&   r+   r   r   r(   r,   r-   r   rT   r)   r/   r@   rA   rB   r   r   r  r   rc   r.  assertGreaterEqualassertLessEqualrC   )r1   re   rE   r!  r"  initial_non_null_valuesrg   r   r   r   r#  r$  updated_resultfieldsinitial_valueupdated_valuer  r  s                     r4   -test_bazi_get_api_update_preserves_all_valueszGAPIResponseStructureTests.test_bazi_get_api_update_preserves_all_valuesF  sk    &&%cd4B>OB|		 ' 
 	 'vyy0AB{{s+1137#((* #%h' 7Ff~24'/$*6N$8$8$:LE5(AF/7> %; 7 !q"- {{s+1137#((* &h/5;;=NFF  !776(Jc9def%,2LLN(E=$26$:$>$>u$EM((%$VHAeW4ij "-#u>:m^ach]iCj(A- 33M1PQRWQXXsFtu(B. 00vhaPUwVtDuv -;	 >( K$E  !6*UGKd8ef % -(:fn]&C|TZS[[qErs,];FC$$[LHb2cdMM%VHLf6ghMM';,vhNj8kl((U);|F8Sq=rs((W)=fXUu?vw ; )r6   N)__name__
__module____qualname____doc__r5   rH   rj   rp   rx   r}   r   r   r   r   r   r   r  r%  r*  r2  r<   r6   r4   r   r      sx    TG.)&HAT?QD=AB6AtWk 5(*OX7Krc>NY`GDR%oNJwXMxr6   r   )
__future__r   django.testr   django.contrib.authr   django.urlsr   datetimer   r   rB   bazi.modelsr	   iching.utils.bazi_relationsr
   r   r   r   r   r   r   rA  r6   r4   <module>rI     s4    "   .     
Dx Dxr6   