
    Hi2                        d Z ddlZddlmc mZ ddlZddlZddl	Z	ddl
Z
ddlZddlZddlZddlmZ ddlZ eej$                  j'                  dd            Z ee      e
j,                  vr"e
j,                  j/                  d ee             dddd	d
ddddddd	i ddddddddddddgi dZg dZej4                  d        Zej4                  d        ZdefdZded efd!Z G d" d#      Z y)$u   banner-versions API 테스트.

GET /api/banner-versions 와 POST /api/banner-versions/select 엔드포인트를
임시 HTTP 서버로 띄워 검증합니다.
    N)PathWORKSPACE_ROOTz/home/jay/workspaceztask-1456.1u   버전 C (task-1456.1)u   Cycle 2 수정TZ   U   cell-1-testcell-2-test)task_idlabeldescription	available	dq_scoresztask-1460.1u   피드백 수정 버전u   피드백 기반 수정v1456v1460r   zCell 1testztest-concept)idr   brandconceptr	   zCell 2ztest-concept2)versionscells
selections)zmeta-feed-1080x1080.htmlzmeta-feed-1080x1080.pngzgoogle-resp-1200x628.htmlzgoogle-resp-1200x628.pngc                    | dz  dz  }|j                  d       |dz  }|j                  t        j                  t        dd      d	
       dD ]V  }dD ]O  }| dz  dz  dz  |z  |z  }|j                  d       t
        D ]!  }||z  j                  d| d| d| d	
       # Q X | dz  dz  j                  dd       | dz  dz  j                  dd       | |fS )u5   격리된 배너 테스트 환경을 구성합니다.	dashboarddataT)parentszbanner-versions.jsonF   )ensure_asciiindentzutf-8)encodingr   r   outputbannersr   zdummy--)r   exist_okmemorylogs)mkdir
write_textjsondumps_BV_DATA_BANNER_FILES)tmp_pathdata_dirbv_fileversioncellcell_dirfnames          1/home/jay/workspace/tests/test_banner_versions.pybanner_test_envr5   I   s*    +%.HNN4N //G

8%:W  
 & 	2 	D8#i/*<wFM  NN4N(& E!--WIQtfAeW5 . 		 9$++D4+H 6!(((EW    c              #     K   | \  }ddl m} ddlm} ddl m}  |      }|j                          |j                  |dt        dz  dz               ddlm	} |j                  |dt        dz  dz               ddl
m} |j                  |dt        dz  d	z                G fd
d|      }	||	_        dt        j                  _        t        j                  d|	      5 }
|
j                   d   }t#        j$                  |
j&                  d      }|j)                          d| f |
j+                          ddd       y# 1 sw Y   yxY ww)u;   배너 API 테스트용 임시 HTTP 서버를 띄웁니다.r   N)
DataLoader)DashboardHandler__file__r   z	server.pyzroutes_post.pyzroutes_get.pyc                       e Zd Z fdZy)&test_server.<locals>.TestBannerHandlerc                     dz  | _         t        ddg      } |j                  j                  | g|dt	              i| y )Nr   zhttp.serverSimpleHTTPRequestHandler)fromlist	directory)dashboard_dir
__import__r>   __init__str)selfargskwargshttp_server_baser-   s       r4   rC   z/test_server.<locals>.TestBannerHandler.__init__   sY     "*K!7D)-C]B^_>55>>'*8}8>r6   N)__name__
__module____qualname__rC   )r-   s   r4   TestBannerHandlerr<      s    	r6   rL   T)z	127.0.0.1r      )targetdaemonzhttp://127.0.0.1:)dashboard.serverserverdashboard.data_loaderr8   r9   
reload_allsetattrrD   dashboard.routes_postroutes_postdashboard.routes_get
routes_getdata_loadersocketserverThreadingTCPServerallow_reuse_addressserver_address	threadingThreadserve_foreverstartshutdown)r5   monkeypatch_
server_modr8   r9   loaderroutes_post_modroutes_get_modrL   httpdactual_portthreadr-   s                @r4   test_serverrl   i   sJ     "KHa)01 !F

 JH{$:[$H I 4SK)?BR)R%S 2
C;(>(P$Q
,  %+!:>L##7		(	(+
 	**1-!!)<)<TJ!+/99  s   C!E$AE>	EEEurlc                    t         j                  j                  |       }t         j                  j                  |      5 }|j                  t        j                  |j                               fcddd       S # 1 sw Y   yxY w)u"   GET 요청 → (status, body_dict)N)urllibrequestRequesturlopenstatusr)   loadsread)rm   reqresps      r4   _getrx      sZ    
..
 
 
%C				$ 4{{DJJtyy{334 4 4s   /A88Br   c                    t        j                  |      j                         }t        j                  j                  | |ddi      }	 t        j                  j                  |      5 }|j                  t        j                  |j                               fcddd       S # 1 sw Y   yxY w# t        j                  j                  $ r9}|j                  t        j                  |j                               fcY d}~S d}~ww xY w)uG   POST 요청 → (status, body_dict) — 4xx/5xx 도 파싱해서 반환zContent-Typezapplication/json)r   headersN)r)   r*   encodero   rp   rq   rr   rs   rt   ru   error	HTTPErrorcode)rm   r   bodyrv   rw   es         r4   _postr      s    ::d""$D
..
 
 $1C D ! C,^^##C( 	8D;;

499; 77	8 	8 	8<<!! ,vvtzz!&&(+++,s<   	B- (/B!	B- !B*&B- *B- -D
.C>8D>Dc                   4    e Zd ZdZd Zd Zd Zd Zd Zd Z	y)	TestBannerVersionsAPIu   Banner versions API 테스트.c           	         |\  }}t        | d      \  }}d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j
                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  d| d|       d	z   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  }t        j                  d      d	z   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  }t        j                  d      d	z   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  }t        j                  d      d	z   d
|iz  }	t        t        j                  |	            dx}
}|d   }t        |t              }|s!t        j                  d      dz   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
                  t              rt        j                  t              ndt        j                  |      dz  }t        t        j                  |            d}t        |      }d}||k\  }|st        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  }t        j                  d t        |             d!z   d"|iz  }t        t        j                  |            dx}x}}|D ch c]  }|d#   	 }}d$}
|
|v }|st        j                  d|fd|
|f      t        j                  |
      d%t        j                         v st        j
                  |      rt        j                  |      nd%dz  }t        j                  d&      d	z   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  }t        j                  d(      d	z   d
|iz  }	t        t        j                  |	            dx}
}|D ]  }d)D ]  }||v }|st        j                  d|fd*||f      d+t        j                         v st        j
                  |      rt        j                  |      nd+d,t        j                         v st        j
                  |      rt        j                  |      nd,d-z  }t        j                  d.| d/|       d0z   d1|iz  }t        t        j                  |            d}  |d   }t        |t              }|s!t        j                  d2      dz   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
                  t              rt        j                  t              ndt        j                  |      dz  }t        t        j                  |            d}t        |      }d}||k\  }|st        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  }t        j                  d3t        |             d!z   d"|iz  }t        t        j                  |            dx}x}}|D ]  }d#}
|
|v }|st        j                  d|fd|
|f      t        j                  |
      d4t        j                         v st        j
                  |      rt        j                  |      nd4dz  }t        j                  d5|       d	z   d
|iz  }	t        t        j                  |	            dx}
}d6}
|
|v }|st        j                  d|fd|
|f      t        j                  |
      d4t        j                         v st        j
                  |      rt        j                  |      nd4dz  }t        j                  d7|       d	z   d
|iz  }	t        t        j                  |	            dx}
} yc c}w )8u;   GET /api/banner-versions — 정상 응답 + 구조 검증./api/banner-versions   ==z%(py0)s == %(py3)srs   py0py3   예상 200, 실제 : 
>assert %(py5)spy5Nr   inz%(py1)s in %(py3)sr   py1r   u   응답에 'versions' 키 없음r   u   응답에 'cells' 키 없음r   u!   응답에 'selections' 키 없음u"   'versions' 는 리스트여야 함z7
>assert %(py4)s
{%(py4)s = %(py0)s(%(py1)s, %(py2)s)
}
isinstancelist)r   r   py2py4r   )>=)z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} >= %(py6)slen)r   r   r   py6u)   버전이 최소 2개여야 함, 실제: z
>assert %(py8)spy8r   r   version_idsu    v1456 버전이 응답에 없음r   u    v1460 버전이 응답에 없음)r   r   r   r   r   )z%(py0)s in %(py2)skeyv)r   r   u   version 항목에 'u   ' 키 없음: z
>assert %(py4)sr   u   'cells' 는 리스트여야 함u&   셀이 최소 2개여야 함, 실제: cu    cell 항목에 'id' 키 없음: nameu"   cell 항목에 'name' 키 없음: )rx   
@pytest_ar_call_reprcompare@py_builtinslocals_should_repr_global_name	_saferepr_format_assertmsgAssertionError_format_explanationr   r   r   )rE   rl   base_urlrd   rs   r   @py_assert2@py_assert1@py_format4@py_format6@py_assert0r   @py_assert3@py_format5@py_assert5@py_assert4@py_format7@py_format9r   r   r   @py_format3r   r   s                           r4    test_get_banner_versions_successz6TestBannerVersionsAPI.test_get_banner_versions_success   s   !!xj(<=>Dv}DDDvDDDDDDvDDDvDDDDDD 3F82dVDDDDDDD DzT!DDDzTDDDzDDDDDDTDDDTDDDD#DDDDDDD>w$>>>w$>>>w>>>>>>$>>>$>>>> >>>>>>>H|t#HHH|tHHH|HHHHHHtHHHtHHHH%HHHHHHH 
#(D)O)OO+OOOOOOOzOOOzOOOOOO(OOO(OOOOOODOOODOOO)OOOOOO8}^^}!^^^}^^^^^^s^^^s^^^^^^8^^^8^^^}^^^^^^%NsS[}o#^^^^^^^^(011qw11Iw+%IIIw+IIIwIIIIII+III+IIII'IIIIIIIIw+%IIIw+IIIwIIIIII+III+IIII'IIIIIII 	NAK NaxMMMsaMMMMMMsMMMsMMMMMMaMMMaMMMM#6se>!!MMMMMMMN	N
 W%&I&II(IIIIIIIzIIIzIIIIII%III%IIIIIIIIIIII&IIIIII5zUQUzQUUUzQUUUUUUsUUUsUUUUUU5UUU5UUUzUUUQUUU"HU UUUUUUUU 	IAD419DDD41DDD4DDDDDD1DDD1DDDD @DDDDDDDH6Q;HHH6QHHH6HHHHHHQHHHQHHHH"DQC HHHHHHHH	I 2s   <o,c                 	   |\  }}ddd}t        | d|      \  }}d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j
                  |      rt        j                  |      ndt        j                  |      d	z  }	t        j                  d
| d|       dz   d|	iz  }
t        t        j                  |
            dx}}|j                  }d} ||      }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                  |      dz  }dd|iz  }t        t        j                  |            dx}x}x}x}}|j                  }d} ||      }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                  |      dz  }dd|iz  }t        t        j                  |            dx}x}x}x}}|j                  }d} ||      }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                  |      dz  }dd|iz  }t        t        j                  |            dx}x}x}x}}|dz  dz  dz  }t        D ]  }||z  }|j                  } |       }|st        j                  d||z         dz   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                  |      t        j                  |      dz  }t        t        j                  |            dx}x}} y)u9   POST /api/banner-versions/select — v1456 선택 성공.r   r   cell_idr0   /api/banner-versions/selectr   r   r   rs   r   r   r   r   r   NokzI%(py6)s
{%(py6)s = %(py2)s
{%(py2)s = %(py0)s.get
}(%(py4)s)
} == %(py9)sr   r   r   r   r   py9assert %(py11)spy11r   r0   r!   r"      복사된 파일 없음: O
>assert %(py6)s
{%(py6)s = %(py4)s
{%(py4)s = (%(py0)s / %(py1)s).exists
}()
}dst_dirr3   r   r   r   r   r   r   r   r   r   r   r   r   r   r   getr,   existsrE   rl   r   r-   payloadrs   r   r   r   r   r   r   r   @py_assert8@py_assert7@py_format10@py_format12r   r3   r   s                       r4   test_post_select_v1456_successz4TestBannerVersionsAPI.test_post_select_v1456_success   !   ((+@z)DEwODv}DDDvDDDDDDvDDDvDDDDDD 3F82dVDDDDDDDxx))x!)T)!T))))!T))))))t)))t)))x))))))!)))T)))))))xx3	3x	"3m3"m3333"m333333t333t333x333	333"333m3333333xx-	-x	"-g-"g----"g------t---t---x---	---"---g------- X%	1MA" 	]EeO\O++\+-\-\\1J7UZ?J[/\\\\\\\G\\\G\\\\\\e\\\e\\\+\\\-\\\\\\	]r6   c                 	   |\  }}ddd}t        | d|      \  }}d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j
                  |      rt        j                  |      ndt        j                  |      d	z  }	t        j                  d
| d|       dz   d|	iz  }
t        t        j                  |
            dx}}|j                  }d} ||      }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                  |      dz  }dd|iz  }t        t        j                  |            dx}x}x}x}}|j                  }d} ||      }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                  |      dz  }dd|iz  }t        t        j                  |            dx}x}x}x}}|j                  }d} ||      }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                  |      dz  }dd|iz  }t        t        j                  |            dx}x}x}x}}|dz  dz  dz  }t        D ]  }||z  }|j                  } |       }|st        j                  d||z         dz   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                  |      t        j                  |      dz  }t        t        j                  |            dx}x}} y)u9   POST /api/banner-versions/select — v1460 선택 성공.r	   r   r   r   r   r   r   rs   r   r   r   r   r   Nr   r   r   r   r   r   r   r0   r!   r"   r   r   r   r3   r   r   r   s                       r4   test_post_select_v1460_successz4TestBannerVersionsAPI.test_post_select_v1460_success   r   r6   c                    |\  }}t        | dddd      \  }}d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j
                  |      rt        j                  |      ndt        j                  |      d	z  }t        j                  d
|       dz   d|iz  }	t        t        j                  |	            dx}}t        | d      \  }
}d}|
|k(  }|st        j                  d|fd|
|f      dt        j                         v st        j
                  |
      rt        j                  |
      ndt        j                  |      d	z  }t        j                  d|       dz   d|iz  }	t        t        j                  |	            dx}}|j                  di       }|j                  }d} ||      }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                  |      dz  }t        j                  d|       dz   d|iz  }t        t        j                  |            dx}x}x}x}}y)u-   POST 후 GET — selections에 반영 확인.r   r   r   r   r   r   r   post_statusr   u   POST 실패: r   r   Nr   
get_statusu   GET 실패: r   r   r   u-   selections 에 선택 상태 반영 안 됨: z
>assert %(py11)sr   )r   r   r   r   r   r   r   r   r   r   rx   r   )rE   rl   r   rd   r   	post_bodyr   r   r   r   r   get_bodyr   r   r   r   r   r   r   s                      r4   &test_post_then_get_selection_persistedz<TestBannerVersionsAPI.test_post_then_get_selection_persisted  s-   !! "'j34%':"
Y ">{c!>>>{c>>>>>>{>>>{>>>c>>>]9+#>>>>>>>  $xj0D$EF
H ;zS ;;;zS;;;;;;z;;;z;;;S;;;L
";;;;;;;\\,3
~~ 	
m 	
~m, 	
 	
,7 	
 	
, 	
 	
	6	
 	
   	
 	
 		  	
 	
 		  	
 	
 		 , 	
 	
 		 - 	
 	
 		 18 	
 	
  <J<H	
 	
 	
 	
 	
 	
r6   c                 n   |\  }}t        | dddd      \  }}d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j
                  |      rt        j                  |      ndt        j                  |      d	z  }t        j                  d
| d|       dz   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  }t        j                  d|       dz   d|iz  }	t        t        j                  |	            dx}
}d}
|d   }|
|v }|st        j                  d|fd|
|f      t        j                  |
      t        j                  |      dz  }t        j                  d|d          dz   d|iz  }t        t        j                  |            dx}
x}}y)u1   존재하지 않는 버전 선택 시 400 에러.r   r   zv-nonexistentr     r   r   rs   r      예상 400, 실제 r   r   r   Nr|   r   r   r   r      응답에 'error' 키 없음: zInvalid versionz%(py1)s in %(py4)sr   r   u.   에러 메시지에 'Invalid version' 없음: 
>assert %(py6)sr   
r   r   r   r   r   r   r   r   r   r   rE   rl   r   rd   rs   r   r   r   r   r   r   r   r   r   s                 r4    test_post_select_invalid_versionz6TestBannerVersionsAPI.test_post_select_invalid_version)  s   !!j34%/B

 Dv}DDDvDDDDDDvDDDvDDDDDD 3F82dVDDDDDDDGw$GGGw$GGGwGGGGGG$GGG$GGGG"@ GGGGGGG  	
DM 	
 M1 	
 	
 M 	
 	
 		 ! 	
 	
 		 %2 	
 	
  =T']OL	
 	
 	
 	
 	
 	
r6   c                 n   |\  }}t        | dddd      \  }}d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j
                  |      rt        j                  |      ndt        j                  |      d	z  }t        j                  d
| d|       dz   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  }t        j                  d|       dz   d|iz  }	t        t        j                  |	            dx}
}d}
|d   }|
|v }|st        j                  d|fd|
|f      t        j                  |
      t        j                  |      dz  }t        j                  d|d          dz   d|iz  }t        t        j                  |            dx}
x}}y)u(   잘못된 cell_id 선택 시 400 에러.r   zcell-invalidr   r   r   r   r   rs   r   r   r   r   r   Nr|   r   r   r   r   r   zInvalid cell_idr   r   u.   에러 메시지에 'Invalid cell_id' 없음: r   r   r   r   s                 r4    test_post_select_invalid_cell_idz6TestBannerVersionsAPI.test_post_select_invalid_cell_id:  s   !!j34&7;

 Dv}DDDvDDDDDDvDDDvDDDDDD 3F82dVDDDDDDDGw$GGGw$GGGwGGGGGG$GGG$GGGG"@ GGGGGGG  	
DM 	
 M1 	
 	
 M 	
 	
 		 ! 	
 	
 		 %2 	
 	
  =T']OL	
 	
 	
 	
 	
 	
r6   N)
rI   rJ   rK   __doc__r   r   r   r   r   r    r6   r4   r   r      s'    (
 IJ]&]&
.
"
r6   r   )!r   builtinsr   _pytest.assertion.rewrite	assertionrewriter   r)   osrZ   sysr^   urllib.errorro   urllib.requestpathlibr   pytestenvironr   
_WORKSPACErD   pathinsertr+   r,   fixturer5   rl   rx   dictr   r   r   r6   r4   <module>r      s=     	  
     "**..!13HIJ
z?#(("HHOOAs:' %-+)+B?
 %.4
$  %		
  &		
 ? D  > 6 6|4c 4
,s 
,$ 
,$E
 E
r6   