
    GiNi              	       2   U 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mZ ddlmZ ddlmZmZ ddlmZmZmZ ddlZe	j.                  j1                  d e ee      j6                  j6                               dZee   ed<   	 ddlZedu Z ejB                  jE                  e d	      Z#d
Z$dZ%dZ&	 	 d!dedede'defdZ(dedede)e   f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       Z0y# e$ r Y w xY w)"u  TDD RED 단계: test_insurance_spider.py

Scrapling Spider ABC를 상속한 InsuranceSpider 클래스와
ResponseHistory 유틸리티에 대한 테스트 스위트.
(insurance_spider.py는 아직 구현되지 않음 - TDD RED 단계)

주의:
- 모든 테스트는 로컬에서 수행 (mock 사용). 외부 네트워크 호출 없음.
- 실제 크롤링 시 반드시 대상 사이트의 robots.txt를 확인하고 준수해야 합니다.
- 합법적 공개 데이터(보험사 공시 페이지 등)만을 대상으로 합니다.
    N)Path)
ModuleType)AnyOptional)	AsyncMock	MagicMockpatch_insurance_spideruH   insurance_spider.py 미구현 (TDD RED 단계 - 토르가 구현 예정))reasonu  
<html>
<body>
  <div class="product">
    <span class="name">화재보험</span>
    <span class="price">50000</span>
  </div>
  <div class="product">
    <span class="name">자동차보험</span>
    <span class="price">100000</span>
  </div>
  <div class="product">
    <span class="name">생명보험</span>
    <span class="price">30000</span>
  </div>
  <a class="next-page" href="/products?page=2">다음</a>
</body>
</html>
u   
<html>
<body>
  <table>
    <tr><th>보험명</th><th>보험료</th><th>가입기간</th></tr>
    <tr><td>화재보험</td><td>50000</td><td>1년</td></tr>
    <tr><td>자동차보험</td><td>100000</td><td>1년</td></tr>
  </table>
</body>
</html>
z
<html>
<body>
  <div class="product">
    <span class="name"></span>
    <span class="price"></span>
  </div>
</body>
</html>
htmlurlstatusreturnc                 D    ddl m}  || |d      }||_        i |_        |S )u   Selector를 Response 대용으로 사용 (Response는 Selector 상속).

    추가 속성(status, meta)만 동적으로 붙인다.
    r   )SelectorF)r   adaptive)scrapling.parserr   r   meta)r   r   r   r   sels        :/home/jay/workspace/scripts/tests/test_insurance_spider.pymake_mock_responser   X   s(     *
4S5
1CCJCHJ    spiderresponsec                 p   K   g }| j                  |      2 3 d{   }|j                  |       7 6 |S w)u9   parse() async generator의 결과를 리스트로 수집.N)parseappend)r   r   resultsitems       r   collect_parse_resultsr    i   s=     Gll8,  dt,Ns   6313636c                       e Zd ZdZedd       Zedd       Zedd       Zedd       Zedd       Z	edd       Z
edd	       Zedd
       Zy)TestResponseHistoryu$   ResponseHistory 클래스 테스트.Nc                 `   d}t         |u}|st        j                  d|fdt         |f      dt        j                         v st        j
                  t               rt        j                  t               ndt        j                  |      dz  }dd|iz  }t        t        j                  |            dx}}t        j                         }|j                  } |       }g }||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                  |      dz  }	dd|	iz  }
t        t        j                  |
            dx}x}x}}y)u:   기본 생성 시 히스토리가 비어 있어야 한다.Nis notz%(py0)s is not %(py3)sr
   py0py3assert %(py5)spy5==zJ%(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.get_history
}()
} == %(py7)shistoryr(   py2py4py7assert %(py9)spy9)r
   
@pytest_ar_call_reprcompare@py_builtinslocals_should_repr_global_name	_safereprAssertionError_format_explanationResponseHistoryget_history)self@py_assert2@py_assert1@py_format4@py_format6r/   @py_assert3@py_assert6@py_assert5@py_format8@py_format10s              r   test_default_initz%TestResponseHistory.test_default_inity   s     )-, ,,,, ,,,,,, ,,, ,,,,,,,,,,#335""*"$**$****$******w***w***"***$**********r   c                    d}t         |u}|st        j                  d|fdt         |f      dt        j                         v st        j
                  t               rt        j                  t               ndt        j                  |      dz  }dd|iz  }t        t        j                  |            dx}}t        j                         }|j                  dd	       |j                         }t        |      }d
}||k(  }|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   }d}||k(  }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }	t        t        j                  |	            dx}x}}|d   d   }d	}||k(  }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }	t        t        j                  |	            dx}x}}y)u<   record() 후 get_history()에 항목이 나타나야 한다.Nr$   r&   r
   r'   r*   r+   https://example.com      r,   z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} == %(py6)slenresultr(   py1r)   py6assert %(py8)spy8r   r   z%(py1)s == %(py4)srS   r2   assert %(py6)srT   r   r
   r6   r7   r8   r9   r:   r;   r<   r=   r>   recordr?   rP   r@   rA   rB   rC   rD   r/   rQ   rG   @py_assert4@py_format7@py_format9@py_assert0rE   @py_format5s                 r   test_record_and_get_historyz/TestResponseHistory.test_record_and_get_history   s    )-, ,,,, ,,,,,, ,,, ,,,,,,,,,,#335,c2$$&6{a{a{ass66{aay8#88#88888#8888888#88888888ay")c)"c))))"c)))")))c)))))))r   c                 T   d}t         |u}|st        j                  d|fdt         |f      dt        j                         v st        j
                  t               rt        j                  t               ndt        j                  |      dz  }dd|iz  }t        t        j                  |            dx}}t        j                         }|j                  dd	       |j                  d
d       |j                  dd       |j                         }t        |      }d}||k(  }|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   }d}||k(  }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }	t        t        j                  |	            dx}x}}|d   d   }d}||k(  }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }	t        t        j                  |	            dx}x}}|d   d   }d}||k(  }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }	t        t        j                  |	            dx}x}}y)uM   여러 번 record() 시 모든 항목이 순서대로 보존되어야 한다.Nr$   r&   r
   r'   r*   r+   https://example.com/arM   https://example.com/b-  zhttps://example.com/ci     r,   rO   rP   rQ   rR   rU   rV   r   r   rW   rX   rY   rT   rN   r      rZ   r\   s                 r   test_record_multiple_entriesz0TestResponseHistory.test_record_multiple_entries   s<    )-, ,,,, ,,,,,, ,,, ,,,,,,,,,,#335.4.4.4$$&6{a{a{ass66{aay:#::#:::::#:::::::#::::::::ay")c)"c))))"c)))")))c)))))))ay")c)"c))))"c)))")))c)))))))r   c                 ~   d}t         |u}|st        j                  d|fdt         |f      dt        j                         v st        j
                  t               rt        j                  t               ndt        j                  |      dz  }dd|iz  }t        t        j                  |            dx}}t        j                         }|j                  dd	       |j                  d
d       |j                  d      }t        |      }d}||k\  }|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        }t        |      }|sddt        j                         v st        j
                  t              rt        j                  t              ndt        j                  |      t        j                  |      dz  }t        t        j                  |            dx}}y)uE   get_chain()은 특정 URL에 연결된 항목만 반환해야 한다.Nr$   r&   r
   r'   r*   r+   rd   rM   re   rf   rN   >=z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} >= %(py6)srP   chainrR   rU   rV   c              3   ,   K   | ]  }|d    dk(    yw)r   rd   N ).0entrys     r   	<genexpr>z@TestResponseHistory.test_get_chain_single_url.<locals>.<genexpr>   s     Nu5<#::Ns   ,assert %(py4)s
{%(py4)s = %(py0)s(%(py2)s)
}anyr(   r1   r2   )r
   r6   r7   r8   r9   r:   r;   r<   r=   r>   r[   	get_chainrP   ru   )r@   rA   rB   rC   rD   r/   rn   rG   r]   r^   r_   rE   ra   s                r   test_get_chain_single_urlz-TestResponseHistory.test_get_chain_single_url   s    )-, ,,,, ,,,,,, ,,, ,,,,,,,,,,#335.4.4!!"9:5zQzQzQss55zQNNNsNNNNNNNNNsNNNsNNNNNNNNNNNNNNr   c                    d}t         |u}|st        j                  d|fdt         |f      dt        j                         v st        j
                  t               rt        j                  t               ndt        j                  |      dz  }dd|iz  }t        t        j                  |            dx}}t        j                         }dd	g}|j                  d
d|       |j                  d
      }t        |      }d}||k\  }	|	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 }|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   }||k(  }|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)uL   redirects 인자를 통해 리다이렉트 체인이 보존되어야 한다.Nr$   r&   r
   r'   r*   r+   zhttps://example.com/oldzhttps://example.com/redirectzhttps://example.com/newrM   )	redirectsrN   rk   rm   rP   rn   rR   rU   rV   r   rz   inz%(py1)s in %(py3)srr   rS   r)   r,   )z%(py1)s == %(py3)s)r
   r6   r7   r8   r9   r:   r;   r<   r=   r>   r[   rw   rP   )r@   rA   rB   rC   rD   r/   rz   rn   rG   r]   r^   r_   rr   r`   s                 r   test_redirect_chain_preservedz1TestResponseHistory.test_redirect_chain_preserved   s    )-, ,,,, ,,,,,, ,,, ,,,,,,,,,,#335.0NO	% 	 	

 !!";<5zQzQzQss55zQa#{e####{e###{######e###e#######[!.!Y....!Y...!......Y...Y.......r   c                 
   d}t         |u}|st        j                  d|fdt         |f      dt        j                         v st        j
                  t               rt        j                  t               ndt        j                  |      dz  }dd|iz  }t        t        j                  |            dx}}t        j                         }dd	d
}|j                  dd|       |j                         }t        |      }d}||k(  }	|	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   }|j                  }d}	 ||	      }||k(  }|st        j                  d|fd||f      t        j                  |      t        j                  |      t        j                  |	      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}x}x}	x}}y)u3   headers 인자가 기록에 포함되어야 한다.Nr$   r&   r
   r'   r*   r+   z	text/htmlvalue)zContent-TypezX-CustomrL   rM   )headersrN   r,   rO   rP   rQ   rR   rU   rV   r   r   )zI%(py7)s
{%(py7)s = %(py3)s
{%(py3)s = %(py1)s.get
}(%(py5)s)
} == %(py9)s)rS   r)   r+   r3   r5   zassert %(py11)spy11)r
   r6   r7   r8   r9   r:   r;   r<   r=   r>   r[   r?   rP   get)r@   rA   rB   rC   rD   r/   r   rQ   rG   r]   r^   r_   r`   rF   @py_assert8rI   @py_format12s                    r   test_record_with_headersz,TestResponseHistory.test_record_with_headers   s    )-, ,,,, ,,,,,, ,,, ,,,,,,,,,,#335#.GD,c7C$$&6{a{a{ass66{aay2y}}2Y2}Y'2'72222'7222y222}222Y222'2222227222722222222r   c                 |	   d}t         |u}|st        j                  d|fdt         |f      dt        j                         v st        j
                  t               rt        j                  t               ndt        j                  |      dz  }dd|iz  }t        t        j                  |            dx}}t        j                         }|j                  dd	       |j                  d
d	       t        j                         5 }t        |      dz  }|j                  t        |             |j                   } |       }|sddt        j                         v st        j
                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }	t        t        j                  |	            dx}}t#        j$                  |j'                  d            }
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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(  }|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   }d}||k(  }|slt        j                  d|fd||f      t        j                  |      t        j                  |      d z  }	d!d"|	iz  }t        t        j                  |            dx}x}}ddd       y# 1 sw Y   yxY w)#u=   save()는 히스토리를 JSON 파일로 저장해야 한다.Nr$   r&   r
   r'   r*   r+   rL   rM   zhttps://example.com/page2zhistory.jsonAassert %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.exists
}()
}pathrv   zutf-8)encoding5assert %(py4)s
{%(py4)s = %(py0)s(%(py1)s, %(py2)s)
}
isinstancedatalistr(   rS   r1   r2   rh   r,   rO   rP   rR   rU   rV   r   r   rW   rX   rY   rT   )r
   r6   r7   r8   r9   r:   r;   r<   r=   r>   r[   tempfileTemporaryDirectoryr   savestrexistsjsonloads	read_textr   r   rP   )r@   rA   rB   rC   rD   r/   tmpdirr   rE   ra   r   rG   r]   r^   r_   r`   s                   r   test_save_to_json_filez*TestResponseHistory.test_save_to_json_file   s    )-, ,,,, ,,,,,, ,,, ,,,,,,,,,,#335,c22C8((* 	;f<.0DLLT#;; ;= =     4   4   ;   =      ::dnngn>?DdD)))))))):))):))))))d)))d))))))D)))D))))))))))t9!!9>!!!9!!!!!!3!!!3!!!!!!t!!!t!!!9!!!!!!!!!!75>:%::>%:::::>%::::>:::%::::::::	; 	; 	;s   N'R22R;c           	      D   d}t         |u}|st        j                  d|fdt         |f      dt        j                         v st        j
                  t               rt        j                  t               ndt        j                  |      dz  }dd|iz  }t        t        j                  |            dx}}t        j                         }|j                  dd	       |j                  } |       }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                  |      t        j                  |      t        j                  |      dz  }
dd|
iz  }t        t        j                  |            dx}x}x}x}	}|j                          |j                  } |       }g }||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                  |      dz  }dd|iz  }t        t        j                  |            dx}x}x}}y)u4   clear() 후 히스토리가 비어 있어야 한다.Nr$   r&   r
   r'   r*   r+   rL   rM   rN   r,   )zi%(py7)s
{%(py7)s = %(py0)s(%(py5)s
{%(py5)s = %(py3)s
{%(py3)s = %(py1)s.get_history
}()
})
} == %(py10)srP   r/   )r(   rS   r)   r+   r3   py10zassert %(py12)spy12r.   r0   r4   r5   )r
   r6   r7   r8   r9   r:   r;   r<   r=   r>   r[   r?   rP   clear)r@   rA   rB   rC   rD   r/   r]   rF   @py_assert9r   @py_format11@py_format13rE   rG   rH   rI   s                   r   
test_clearzTestResponseHistory.test_clear   s    )-, ,,,, ,,,,,, ,,, ,,,,,,,,,,#335,c2&&.&(.s().Q.)Q....)Q......s...s......7...7...&...(...)...Q.......""*"$**$****$******w***w***"***$**********r   r   N)__name__
__module____qualname____doc___skip_if_missingrJ   rb   ri   rx   r   r   r   r   rp   r   r   r"   r"   v   s    .+ + * * * * O O / /  3 3 ; ;  + +r   r"   c                       e Zd ZdZedd       Zedd       Zedd       Zedd       Zedd       Z	edd       Z
edd	       Zedd
       Zy)TestInsuranceSpiderInitu$   InsuranceSpider 초기화 테스트.Nc                 Z   d}t         |u}|st        j                  d|fdt         |f      dt        j                         v st        j
                  t               rt        j                  t               ndt        j                  |      dz  }dd|iz  }t        t        j                  |            dx}}t         j                  }|j                  }d}||k(  }|st        j                  d	|fd
||f      dt        j                         v st        j
                  t               rt        j                  t               ndt        j                  |      t        j                  |      t        j                  |      dz  }dd|iz  }	t        t        j                  |	            dx}x}x}}y)u/   name 속성이 'insurance_spider'여야 한다.Nr$   r&   r
   r'   r*   r+   insurance_spiderr,   )zQ%(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.InsuranceSpider
}.name
} == %(py7)sr0   r4   r5   )r
   r6   r7   r8   r9   r:   r;   r<   r=   InsuranceSpidername)
r@   rA   rB   rC   rD   rE   rF   rG   rH   rI   s
             r   test_name_attributez+TestInsuranceSpiderInit.test_name_attribute   s     )-, ,,,, ,,,,,, ,,, ,,,,,,,,,, 00K055K9KK59KKKKK59KKKKKKK KKK KKK0KKK5KKK9KKKKKKKKr   c                 L   d}t         |u}|st        j                  d|fdt         |f      dt        j                         v st        j
                  t               rt        j                  t               ndt        j                  |      dz  }dd|iz  }t        t        j                  |            dx}}t        j                  dg	      }|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}||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}||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)u\   concurrent_requests=4, concurrent_requests_per_domain=2, download_delay=1.0이어야 한다.Nr$   r&   r
   r'   r*   r+   rL   
start_urls   r,   )z;%(py2)s
{%(py2)s = %(py0)s.concurrent_requests
} == %(py5)sr   r(   r1   r+   assert %(py7)sr3   rh   )zF%(py2)s
{%(py2)s = %(py0)s.concurrent_requests_per_domain
} == %(py5)sg      ?)z6%(py2)s
{%(py2)s = %(py0)s.download_delay
} == %(py5)s)r
   r6   r7   r8   r9   r:   r;   r<   r=   r   concurrent_requestsconcurrent_requests_per_domaindownload_delay	r@   rA   rB   rC   rD   r   r]   rE   rH   s	            r   !test_concurrent_requests_defaultsz9TestInsuranceSpiderInit.test_concurrent_requests_defaults   s    )-, ,,,, ,,,,,, ,,, ,,,,,,,,,,"22?T>UV)).Q.)Q....)Q......v...v...)...Q.......4499499994999999v999v99949999999999$$++$++++$++++++v+++v+++$++++++++++r   c                    d}t         |u}|st        j                  d|fdt         |f      dt        j                         v st        j
                  t               rt        j                  t               ndt        j                  |      dz  }dd|iz  }t        t        j                  |            dx}}dd	g}t        j                  |
      }|j                  }||k(  }|st        j                  d|fd||f      dt        j                         v st        j
                  |      rt        j                  |      nd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)u=   생성자에서 start_urls를 설정할 수 있어야 한다.Nr$   r&   r
   r'   r*   r+   rd   re   r   r,   )z2%(py2)s
{%(py2)s = %(py0)s.start_urls
} == %(py4)sr   urlsrv   rY   rT   )r
   r6   r7   r8   r9   r:   r;   r<   r=   r   r   )
r@   rA   rB   rC   rD   r   r   rE   ra   r^   s
             r   test_start_urls_setz+TestInsuranceSpiderInit.test_start_urls_set   s     )-, ,,,, ,,,,,, ,,, ,,,,,,,,,,')@A"22dC  ( D(((( D((((((v(((v((( ((((((D(((D(((((((r   c                    d}t         |u}|st        j                  d|fdt         |f      dt        j                         v st        j
                  t               rt        j                  t               ndt        j                  |      dz  }dd|iz  }t        t        j                  |            dx}}dd	h}t        j                  d
g|      }|j                  }||k(  }|st        j                  d|fd||f      dt        j                         v st        j
                  |      rt        j                  |      nd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)uB   생성자에서 allowed_domains를 설정할 수 있어야 한다.Nr$   r&   r
   r'   r*   r+   zexample.comzinsurance.co.krrL   )r   allowed_domainsr,   )z7%(py2)s
{%(py2)s = %(py0)s.allowed_domains
} == %(py4)sr   domainsrv   rY   rT   )r
   r6   r7   r8   r9   r:   r;   r<   r=   r   r   )
r@   rA   rB   rC   rD   r   r   rE   ra   r^   s
             r   test_allowed_domains_setz0TestInsuranceSpiderInit.test_allowed_domains_set   s    )-, ,,,, ,,,,,, ,,, ,,,,,,,,,, "34"22-.#
 %%0%0000%000000v000v000%0000000000000000r   c           
         d}t         |u}|st        j                  d|fdt         |f      dt        j                         v st        j
                  t               rt        j                  t               ndt        j                  |      dz  }dd|iz  }t        t        j                  |            dx}}t        j                  dg	      }|j                  }t        |      }d
}t        |      }||k(  }	|	sgt        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t        j                         v st        j
                  t              rt        j                  t              ndt        j                  |      t        j                  |      dz  }
dd|
iz  }t        t        j                  |            dx}x}x}	x}}y)u7   output_dir 기본값은 'crawl_output'이어야 한다.Nr$   r&   r
   r'   r*   r+   rL   r   crawl_outputr,   zp%(py5)s
{%(py5)s = %(py0)s(%(py3)s
{%(py3)s = %(py1)s.output_dir
})
} == %(py11)s
{%(py11)s = %(py7)s(%(py9)s)
}r   r   r(   rS   r)   r+   r3   r5   r   assert %(py13)spy13r
   r6   r7   r8   r9   r:   r;   r<   r=   r   
output_dirr   r@   rA   rB   rC   rD   r   r]   r   @py_assert10rF   r   @py_format14s               r   test_output_dir_defaultz/TestInsuranceSpiderInit.test_output_dir_default  sW    )-, ,,,, ,,,,,, ,,, ,,,,,,,,,,"22?T>UV%%>t%&>~>$~*>>&*>>>>>&*>>>>>>>t>>>t>>>>>>F>>>F>>>%>>>&>>>>>>$>>>$>>>~>>>*>>>>>>>>>r   c           
         d}t         |u}|st        j                  d|fdt         |f      dt        j                         v st        j
                  t               rt        j                  t               ndt        j                  |      dz  }dd|iz  }t        t        j                  |            dx}}t        j                  dgd	
      }|j                  }t        |      }d	}t        |      }||k(  }	|	sgt        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t        j                         v st        j
                  t              rt        j                  t              ndt        j                  |      t        j                  |      dz  }
dd|
iz  }t        t        j                  |            dx}x}x}	x}}y)u=   output_dir을 커스텀으로 설정할 수 있어야 한다.Nr$   r&   r
   r'   r*   r+   rL   z/tmp/test_outputr   r   r,   r   r   r   r   r   r   r   r   s               r   test_output_dir_customz.TestInsuranceSpiderInit.test_output_dir_custom  sa    )-, ,,,, ,,,,,, ,,, ,,,,,,,,,,"22-.)
 %%Bt%&B/AB$/A*BB&*BBBBB&*BBBBBBBtBBBtBBBBBBFBBBFBBB%BBB&BBBBBB$BBB$BBB/ABBB*BBBBBBBBBr   c                 *   d}t         |u}|st        j                  d|fdt         |f      dt        j                         v st        j
                  t               rt        j                  t               ndt        j                  |      dz  }dd|iz  }t        t        j                  |            dx}}t        j                  dg	      }|j                  }d}||u }|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)u4   extraction_config 기본값은 None이어야 한다.Nr$   r&   r
   r'   r*   r+   rL   r   is)z9%(py2)s
{%(py2)s = %(py0)s.extraction_config
} is %(py5)sr   r   r   r3   r
   r6   r7   r8   r9   r:   r;   r<   r=   r   extraction_configr   s	            r   #test_extraction_config_default_nonez;TestInsuranceSpiderInit.test_extraction_config_default_none  s     )-, ,,,, ,,,,,, ,,, ,,,,,,,,,,"22?T>UV''/4/'4////'4//////v///v///'///4///////r   c                    d}t         |u}|st        j                  d|fdt         |f      dt        j                         v st        j
                  t               rt        j                  t               ndt        j                  |      dz  }dd|iz  }t        t        j                  |            dx}}dd	d
did}t        j                  dg|      }|j                  }||k(  }|st        j                  d|fd||f      dt        j                         v st        j
                  |      rt        j                  |      nd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)uD   extraction_config를 딕셔너리로 설정할 수 있어야 한다.Nr$   r&   r
   r'   r*   r+   css.productr   .namemodecss_selectorfieldsrL   r   r   r,   )z9%(py2)s
{%(py2)s = %(py0)s.extraction_config
} == %(py4)sr   configrv   rY   rT   r   )
r@   rA   rB   rC   rD   r   r   rE   ra   r^   s
             r   test_extraction_config_setz2TestInsuranceSpiderInit.test_extraction_config_set  s    )-, ,,,, ,,,,,, ,,, ,,,,,,,,,,PWGXY"22-.$
 ''1'61111'6111111v111v111'111111611161111111r   r   )r   r   r   r   r   r   r   r   r   r   r   r   r   rp   r   r   r   r      s    .L L
 , , ) ) 1 1 ? ? C C 0 0 2 2r   r   c                   |    e Zd ZdZed	d       Zed	d       Zed	d       Zed	d       Zed	d       Z	ed	d       Z
y)
TestInsuranceSpiderParseu,   InsuranceSpider.parse() 메서드 테스트.Nc                    d}t         |u}|st        j                  d|fdt         |f      dt        j                         v st        j
                  t               rt        j                  t               ndt        j                  |      dz  }dd|iz  }t        t        j                  |            dx}}dd	d
ddd}t        j                  dg|      }t        t        d      }t        j                  t        ||            }|D 	cg c]  }	t        |	t               s|	 }
}	t#        |
      }d}||k\  }|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}}g }d}|
d   }||v }|}|sd}|
d   }||v }|}|st        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }|j%                  |       |s_t        j                  dfd f      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}}yc c}	w )&uQ   CSS 모드에서 extraction_config 기반으로 아이템을 추출해야 한다.Nr$   r&   r
   r'   r*   r+   r   r   r   z.pricer   pricer   rL   r   r   rN   rk   rm   rP   itemsrR   rU   rV   r   r   r   r{   )z%(py3)s in %(py6)s)r)   rT   z%(py8)s)z%(py11)s in %(py14)s)r   py14z%(py16)spy16zassert %(py19)spy19)r
   r6   r7   r8   r9   r:   r;   r<   r=   r   r   HTML_PRODUCTSasynciorunr    r   dictrP   r   _format_boolop)r@   rA   rB   rC   rD   r   r   r   r   rr   rG   r]   r^   r_   r`   r   @py_assert13@py_assert12@py_format15@py_format17@py_format18@py_format20s                          r   "test_parse_css_mode_extracts_itemsz;TestInsuranceSpiderParse.test_parse_css_mode_extracts_items2  s    )-, ,,,, ,,,,,, ,,, ,,,,,,,,,,&&:

 #22-.$
 &m9NO++3FHEF#;qz!T':;;5zQzQzQss55zQ8v8q8v!8W8a8W%8888v888v8888888888W888W88888888888888888 <s   M&!M&c                    d}t         |u}|st        j                  d|fdt         |f      dt        j                         v st        j
                  t               rt        j                  t               ndt        j                  |      dz  }dd|iz  }t        t        j                  |            dx}}ddd	}t        j                  d
g|      }t        t        d
      }t        j                  t        ||            }|D 	cg c]  }	t        |	t               s|	 }
}	t#        |
      }d}||k\  }|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        }t%        |      }|sddt        j                         v st        j
                  t$              rt        j                  t$              ndt        j                  |      t        j                  |      dz  }t        t        j                  |            dx}}yc c}	w )u>   table 모드에서 테이블 데이터를 추출해야 한다.Nr$   r&   r
   r'   r*   r+   table)r   table_selectorrL   r   r   rN   rk   rm   rP   r   rR   rU   rV   c              3   0   K   | ]  }d |v xs d|v   yw)u	   보험명col_0Nrp   )rq   r   s     r   rs   zATestInsuranceSpiderParse.test_parse_table_mode.<locals>.<genexpr>X  s!     Ld;$&9'T/9Ls   rt   ru   rv   )r
   r6   r7   r8   r9   r:   r;   r<   r=   r   r   
HTML_TABLEr   r   r    r   r   rP   ru   )r@   rA   rB   rC   rD   r   r   r   r   r   r   rG   r]   r^   r_   rE   ra   s                    r   test_parse_table_modez.TestInsuranceSpiderParse.test_parse_table_modeG  s    )-, ,,,, ,,,,,, ,,, ,,,,,,,,,,%
 #22-.$
 &j6KL++3FHEF#;qz!T':;;5zQzQzQss55zQLeLLsLLLLLLLLLsLLLsLLLLLLLLLLLLLL <s   K#K#c                 N   d}t         |u}|st        j                  d|fdt         |f      dt        j                         v st        j
                  t               rt        j                  t               ndt        j                  |      dz  }dd|iz  }t        t        j                  |            dx}}dd	d
did}t        j                  dg|      }t        t        d      }t        j                  t        ||            }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dt        j                         v st        j
                  t               rt        j                  t               ndt        j                  |	      dz  }
t        t        j                  |
            d}	y)uA   similar 모드에서 유사 요소 추출이 동작해야 한다.Nr$   r&   r
   r'   r*   r+   similarr   r   r   )r   reference_selectorr   rL   r   r   r   r   r   r   r   )r
   r6   r7   r8   r9   r:   r;   r<   r=   r   r   r   r   r   r    r   r   )r@   rA   rB   rC   rD   r   r   r   r   rE   ra   s              r   test_parse_similar_modez0TestInsuranceSpiderParse.test_parse_similar_modeZ  s>    )-, ,,,, ,,,,,, ,,, ,,,,,,,,,,",w'

 #22-.$
 &m9NO++3FHEF'4((((((((z(((z(((((('((('((((((4(((4((((((((((r   c                    d}t         |u}|st        j                  d|fdt         |f      dt        j                         v st        j
                  t               rt        j                  t               ndt        j                  |      dz  }dd|iz  }t        t        j                  |            dx}}dd	d
did}t        j                  dg|      }t        t        d      }t        j                  t        ||            }|D 	cg c]  }	t        |	t               sd|	v s|	 }
}	t#        |
      }d}||k\  }|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   }d}||k(  }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}yc c}	w ) uG   각 아이템에 _source_url 메타데이터가 첨부되어야 한다.Nr$   r&   r
   r'   r*   r+   r   r   r   r   r   rL   r   https://example.com/productsr   _source_urlrN   rk   rm   rP   r   rR   rU   rV   r   r,   rW   rX   rY   rT   r
   r6   r7   r8   r9   r:   r;   r<   r=   r   r   r   r   r   r    r   r   rP   )r@   rA   rB   rC   rD   r   r   r   r   r   r   rG   r]   r^   r_   r`   rE   ra   s                     r   #test_parse_adds_source_url_metadataz<TestInsuranceSpiderParse.test_parse_adds_source_url_metadatal  s    )-, ,,,, ,,,,,, ,,, ,,,,,,,,,,&w'

 #22-.$
 &m9WX++3FHEF#Rqz!T':}PQ?QRR5zQzQzQss55zQQx&H*HH&*HHHHH&*HHHH&HHH*HHHHHHHH Ss   
J? J?%J?c                 ~   d}t         |u}|st        j                  d|fdt         |f      dt        j                         v st        j
                  t               rt        j                  t               ndt        j                  |      dz  }dd|iz  }t        t        j                  |            dx}}dd	l	m
} d
dddidd}t        j                  dg|      }t        t        d      }t        j                  t!        ||            }	|	D 
cg c]  }
t#        |
|      s|
 }}
t%        |      }d}||k\  }|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}}yc c}
w )uO   next_page_selector가 있으면 다음 페이지 Request를 yield해야 한다.Nr$   r&   r
   r'   r*   r+   r   Requestr   r   r   r   z
.next-page)r   r   r   next_page_selectorrL   r   r  r   rN   rk   rm   rP   requestsrR   rU   rV   )r
   r6   r7   r8   r9   r:   r;   r<   r=   scrapling.spidersr  r   r   r   r   r   r    r   rP   )r@   rA   rB   rC   rD   r  r   r   r   r   r   r  rG   r]   r^   r_   s                   r   test_parse_next_page_followz4TestInsuranceSpiderParse.test_parse_next_page_follow  sl    )-, ,,,, ,,,,,, ,,, ,,,,,,,,,,- &w'".	
 #22-.$
 &m9WX++3FHEF&A!*Q*@AAA8}!!}!!!!}!!!!!!s!!!s!!!!!!8!!!8!!!}!!!!!!!!!! Bs   H:#H:c                 h   d}t         |u}|st        j                  d|fdt         |f      dt        j                         v st        j
                  t               rt        j                  t               ndt        j                  |      dz  }dd|iz  }t        t        j                  |            dx}}t        j                  dgd	      }t        t        d
      }t        j                  t        ||            }|D cg c]  }t        |t               s| }	}t#        |	      }d}
||
k(  }|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}}
yc c}w )uJ   extraction_config가 None이면 아이템을 yield하지 않아야 한다.Nr$   r&   r
   r'   r*   r+   rL   r   r   r   r,   rO   rP   r   rR   rU   rV   r  )r@   rA   rB   rC   rD   r   r   r   r   r   rG   r]   r^   r_   s                 r   .test_parse_no_extraction_config_yields_nothingzGTestInsuranceSpiderParse.test_parse_no_extraction_config_yields_nothing  sK    )-, ,,,, ,,,,,, ,,, ,,,,,,,,,,"22-."
 &m9NO++3FHEF#;qz!T':;;5zQzQzQss55zQ <s   H/H/r   )r   r   r   r   r   r   r   r  r  r  r  rp   r   r   r   r   /  s    69 9( M M$ ) )" I I$ " "* 
 
r   r   c                       e Zd ZdZed
d       Zed
d       Zed
d       Zed
d       Zed
d       Z	ed
d       Z
ed
d	       Zy)TestInsuranceSpiderHooksu(   InsuranceSpider 훅 메서드 테스트.Nc                    d}t         |u}|st        j                  d|fdt         |f      dt        j                         v st        j
                  t               rt        j                  t               ndt        j                  |      dz  }dd|iz  }t        t        j                  |            dx}}t        j                         5 }t        |      dz  }t        j                  d	gt        |      
      }t        j                  |j!                  d             |j"                  } |       }|sddt        j                         v st        j
                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }	t        t        j                  |	            dx}}ddd       y# 1 sw Y   yxY w)u0   on_start()는 output_dir을 생성해야 한다.Nr$   r&   r
   r'   r*   r+   spider_outputrL   r   Fresumingr   r   rv   )r
   r6   r7   r8   r9   r:   r;   r<   r=   r   r   r   r   r   r   r   on_startr   )
r@   rA   rB   rC   rD   r   r   r   rE   ra   s
             r    test_on_start_creates_output_dirz9TestInsuranceSpiderHooks.test_on_start_creates_output_dir  s&    )-, ,,,, ,,,,,, ,,, ,,,,,,,,,,((* 	'ff7J&6612z?F KK78$$&$&&&&&&&&:&&&:&&&$&&&&&&&&&&	' 	' 	's   
C;GGc                 :   d}t         |u}|st        j                  d|fdt         |f      dt        j                         v st        j
                  t               rt        j                  t               ndt        j                  |      dz  }dd|iz  }t        t        j                  |            dx}}t        j                         5 }t        j                  dg|	      }t        j                  |j                  d
             ddd       y# 1 sw Y   yxY w)u@   on_start(resuming=True)는 예외 없이 실행되어야 한다.Nr$   r&   r
   r'   r*   r+   rL   r   Tr  )r
   r6   r7   r8   r9   r:   r;   r<   r=   r   r   r   r   r   r  )r@   rA   rB   rC   rD   r   r   s          r   test_on_start_resuming_flagz4TestInsuranceSpiderHooks.test_on_start_resuming_flag  s     )-, ,,,, ,,,,,, ,,, ,,,,,,,,,,((* 	8f&6612!F
 KK67	8 	8 	8s   
>DDc                    d}t         |u}|st        j                  d|fdt         |f      dt        j                         v st        j
                  t               rt        j                  t               ndt        j                  |      dz  }dd|iz  }t        t        j                  |            dx}}t        j                         5 }t        j                  dg|	      }|j                  j                  dd
       t        j                  |j!                  d             t        j                  |j#                                t%        t'        |      j)                  d            }t+        |      }d}||k\  }	|	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d       y# 1 sw Y   yxY w)u?   on_close()는 ResponseHistory를 파일로 저장해야 한다.Nr$   r&   r
   r'   r*   r+   rL   r   rM   Fr  z	*history*rN   rk   rm   rP   history_filesrR   rU   rV   )r
   r6   r7   r8   r9   r:   r;   r<   r=   r   r   r   response_historyr[   r   r   r  on_closer   r   globrP   )r@   rA   rB   rC   rD   r   r   r  rG   r]   r^   r_   s               r   test_on_close_saves_historyz4TestInsuranceSpiderHooks.test_on_close_saves_history  s    )-, ,,,, ,,,,,, ,,, ,,,,,,,,,,((* 	+f&6612!F
 ##**+@#FKK78KK)* f!2!2;!?@M}%**%****%******3***3******}***}***%**********	+ 	+ 	+s   
F0JJc                    d}t         |u}|st        j                  d|fdt         |f      dt        j                         v st        j
                  t               rt        j                  t               ndt        j                  |      dz  }dd|iz  }t        t        j                  |            dx}}dd	l	m
} t        j                  d
g      } |d
      }t        d      }t        j                  |j                  ||             y)u:   on_error()는 예외 없이 에러를 로깅해야 한다.Nr$   r&   r
   r'   r*   r+   r   r
  rL   r   zConnection failed)r
   r6   r7   r8   r9   r:   r;   r<   r=   r  r  r   ConnectionErrorr   r   on_error)	r@   rA   rB   rC   rD   r  r   requesterrors	            r   test_on_error_logs_errorz1TestInsuranceSpiderHooks.test_on_error_logs_error  s     )-, ,,,, ,,,,,, ,,, ,,,,,,,,,,-"22?T>UV/0 34FOOGU34r   c                    d}t         |u}|st        j                  d|fdt         |f      dt        j                         v st        j
                  t               rt        j                  t               ndt        j                  |      dz  }dd|iz  }t        t        j                  |            dx}}t        j                  dg	      }d
dd}t        j                  |j                  |            }||k(  }|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  }dd|iz  }	t        t        j                  |	            d}y)u5   유효한 아이템은 그대로 반환해야 한다.Nr$   r&   r
   r'   r*   r+   rL   r      화재보험50000r   r,   )z%(py0)s == %(py2)srQ   r   )r(   r1   zassert %(py4)sr2   r
   r6   r7   r8   r9   r:   r;   r<   r=   r   r   r   on_scraped_item)
r@   rA   rB   rC   rD   r   r   rQ   @py_format3ra   s
             r   &test_on_scraped_item_passes_valid_itemz?TestInsuranceSpiderHooks.test_on_scraped_item_passes_valid_item  s     )-, ,,,, ,,,,,, ,,, ,,,,,,,,,,"22?T>UV&9V33D9:~vvvr   c                 8   d}t         |u}|st        j                  d|fdt         |f      dt        j                         v st        j
                  t               rt        j                  t               ndt        j                  |      dz  }dd|iz  }t        t        j                  |            dx}}t        j                  dg	      }dd
d}t        j                  |j                  |            }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)uR   모든 값이 None이나 빈 문자열이면 None을 반환해야 한다 (드롭).Nr$   r&   r
   r'   r*   r+   rL   r    r   r   )z%(py0)s is %(py3)srQ   r+  )r@   rA   rB   rC   rD   r   
empty_itemrQ   s           r   'test_on_scraped_item_filters_empty_itemz@TestInsuranceSpiderHooks.test_on_scraped_item_filters_empty_item  s     )-, ,,,, ,,,,,, ,,, ,,,,,,,,,,"22?T>UV.2R%@
V33J?@v~vvvr   c                 8   d}t         |u}|st        j                  d|fdt         |f      dt        j                         v st        j
                  t               rt        j                  t               ndt        j                  |      dz  }dd|iz  }t        t        j                  |            dx}}t        j                  dg	      }d
dd}t        j                  |j                  |            }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}}|d   }d
}	||	k(  }|slt        j                  d|fd||	f      t        j                  |      t        j                  |	      dz  }
dd|
iz  }t        t        j                  |            dx}x}}	y)uG   일부 값만 비어 있는 경우 아이템을 통과시켜야 한다.Nr$   r&   r
   r'   r*   r+   rL   r   r)  r   rQ   r   r,   rW   rX   rY   rT   r+  )r@   rA   rB   rC   rD   r   r   rQ   r`   rE   ra   r^   s               r   )test_on_scraped_item_partial_empty_passeszBTestInsuranceSpiderHooks.test_on_scraped_item_partial_empty_passes  s?    )-, ,,,, ,,,,,, ,,, ,,,,,,,,,,"22?T>UV&6V33D9:!!vT!!!!vT!!!!!!v!!!v!!!T!!!!!!!f~//~////~///~//////////r   r   )r   r   r   r   r   r  r  r!  r'  r.  r2  r4  rp   r   r   r  r    s    2
' 
' 	8 	8 + +  	5 	5     0 0r   r  c                   X    e Zd ZdZedd       Zedd       Zedd       Zedd       Zy)TestInsuranceSpiderRunu<   InsuranceSpider.run() 메서드 및 출력 형식 테스트.Nc                    d}t         |u}|st        j                  d|fdt         |f      dt        j                         v st        j
                  t               rt        j                  t               ndt        j                  |      dz  }dd|iz  }t        t        j                  |            dx}}dd	l	m
}m}m} t        j                  d
g      } | |dd       |ddig            }	t        j                  |d|	      5 }
|j!                         }|
j#                          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}ddd       y# 1 sw Y   yxY w)uD   run()은 start()를 호출하고 CrawlResult를 반환해야 한다.Nr$   r&   r
   r'   r*   r+   r   CrawlResult
CrawlStatsItemListrL   r   rN   rh   requests_countitems_scrapedr   u   보험Astatsr   startreturn_valuer   r   rQ   r9  r   )r
   r6   r7   r8   r9   r:   r;   r<   r=   scrapling.spiders.resultr9  r:  r;  r   r	   objectr   assert_called_oncer   )r@   rA   rB   rC   rD   r9  r:  r;  r   mock_result
mock_startrQ   rE   ra   s                 r   -test_run_calls_start_and_returns_crawl_resultzDTestInsuranceSpiderRun.test_run_calls_start_and_returns_crawl_result  sg    )-, ,,,, ,,,,,, ,,, ,,,,,,,,,,NN"22?T>UV!AQ?VY/01
 \\&'D 	3
ZZ\F))+fk22222222:222:222222f222f222222k222k2222222222	3 	3 	3s   
D5IIc                 *   d}t         |u}|st        j                  d|fdt         |f      dt        j                         v st        j
                  t               rt        j                  t               ndt        j                  |      dz  }dd|iz  }t        t        j                  |            dx}}dd	l	m
}m}m} t        j                         5 }t        j                  d
g|      }	 |ddiddig      }
 | |dd      |
      }t!        j"                  |	d|      5  |	j%                  d       ddd       t'        t)        |      j+                  d            }t-        |      }d}||k\  }|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d       y# 1 sw Y   FxY w# 1 sw Y   yxY w)uB   run(output_format='jsonl')은 JSONL 파일로 내보내야 한다.Nr$   r&   r
   r'   r*   r+   r   r8  rL   r   r   r)  u   자동차보험rh   r<  r?  rA  rB  jsonloutput_formatz*.jsonlrN   rk   rm   rP   jsonl_filesrR   rU   rV   r
   r6   r7   r8   r9   r:   r;   r<   r=   rD  r9  r:  r;  r   r   r   r	   rE  r   r   r   r   rP   )r@   rA   rB   rC   rD   r9  r:  r;  r   r   
mock_itemsrG  rN  rG   r]   r^   r_   s                    r   test_run_exports_jsonlz-TestInsuranceSpiderRun.test_run_exports_jsonl  s    )-, ,,,, ,,,,,, ,,, ,,,,,,,,,,NN((* 	)f&6612!F "FN#;fFW=X"YZJ% C K fgKH 2


12 tF|00;<K{#(q(#q((((#q((((((3(((3(((((({((({(((#(((q(((((((	) 	)2 2	) 	)s&   AJ	%I<8D;J	<J	J		Jc                 $   d}t         |u}|st        j                  d|fdt         |f      dt        j                         v st        j
                  t               rt        j                  t               ndt        j                  |      dz  }dd|iz  }t        t        j                  |            dx}}dd	l	m
}m}m} t        j                         5 }t        j                  d
g|      }	 |ddig      }
 | |dd      |
      }t!        j"                  |	d|      5  |	j%                  d       ddd       t'        t)        |      j+                  d            }t-        |      }d}||k\  }|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d       y# 1 sw Y   FxY w# 1 sw Y   yxY w)u@   run(output_format='json')은 JSON 파일로 내보내야 한다.Nr$   r&   r
   r'   r*   r+   r   r8  rL   r   r   r)  rN   r<  r?  rA  rB  r   rL  z*.jsonrk   rm   rP   
json_filesrR   rU   rV   rO  )r@   rA   rB   rC   rD   r9  r:  r;  r   r   rP  rG  rS  rG   r]   r^   r_   s                    r   test_run_exports_jsonz,TestInsuranceSpiderRun.test_run_exports_json-  s    )-, ,,,, ,,,,,, ,,, ,,,,,,,,,,NN((* 	(f&6612!F "FN#;"<=J% C K fgKH 1


01d6l//9:Jz?'a'?a''''?a''''''3'''3''''''z'''z'''?'''a'''''''	( 	(1 1	( 	(s&   AJ"I95D;J9J	>JJc                 H   d}t         |u}|st        j                  d|fdt         |f      dt        j                         v st        j
                  t               rt        j                  t               ndt        j                  |      dz  }dd|iz  }t        t        j                  |            dx}}t         j                  j                  dd	gd
ddd      }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dt        j                         v st        j
                  t              rt        j                  t              ndt        j                  |      dz  }t        t        j                  |            d}|d   }d}||k(  }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }	t        t        j                  |	            dx}x}}|d   }d	g}||k(  }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }	t        t        j                  |	            dx}x}}|d   }d
}||k(  }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }	t        t        j                  |	            dx}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) uZ   create_cron_config()는 cokacdir --cron 연동 설정 딕셔너리를 반환해야 한다.Nr$   r&   r
   r'   r*   r+   z	0 6 * * *zhttps://example.com/insurancez/data/insurancer   r   )r   r   )scheduler   r   r   r   r   r   r   r   rV  r,   rW   rX   rY   rT   r   r   r   r{   r}   r~   )r
   r6   r7   r8   r9   r:   r;   r<   r=   r   create_cron_configr   r   )
r@   rA   rB   rC   rD   r   rE   ra   r`   r^   s
             r   test_create_cron_configz.TestInsuranceSpiderRun.test_create_cron_configB  sx    )-, ,,,, ,,,,,, ,,, ,,,,,,,,,,"22EE 78(',jI	 F 
 &$''''''''z'''z''''''&'''&''''''$'''$''''''''''j!0[0![0000![000!000[0000000l#H(G'HH#'HHHHH#'HHHH#HHH'HHHHHHHHl#8'88#'88888#'8888#888'88888888","f,,,,"f,,,",,,,,,f,,,f,,,,,,,r   r   )	r   r   r   r   r   rI  rQ  rT  rX  rp   r   r   r6  r6    sS    F3 3 ) )* ( (( - -r   r6  c                   X    e Zd ZdZedd       Zedd       Zedd       Zedd       Zy)TestCheckpointIntegrationu&   Checkpoint(crawldir) 통합 테스트.Nc                     d}t         |u}|st        j                  d|fdt         |f      dt        j                         v st        j
                  t               rt        j                  t               ndt        j                  |      dz  }dd|iz  }t        t        j                  |            dx}}t        j                         5 }t        |      dz  }t        j                  d	gt        |      
      }|j                  }||k(  }|st        j                  d|fd||f      dt        j                         v st        j
                  |      rt        j                  |      nd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dd       y# 1 sw Y   yxY w)uC   crawldir을 지정하면 Spider.crawldir에 반영되어야 한다.Nr$   r&   r
   r'   r*   r+   checkpointsrL   )r   crawldirr,   )z0%(py2)s
{%(py2)s = %(py0)s.crawldir
} == %(py4)sr   r]  rv   rY   rT   )r
   r6   r7   r8   r9   r:   r;   r<   r=   r   r   r   r   r   r]  )r@   rA   rB   rC   rD   r   r]  r   rE   ra   r^   s              r   test_crawldir_is_setz.TestCheckpointIntegration.test_crawldir_is_set[  s-    )-, ,,,, ,,,,,, ,,, ,,,,,,,,,,((* 	/fF|m3H&6612XF ??.?h....?h......6...6...?......h...h.......	/ 	/ 	/s   
D!G44G=c                 *   d}t         |u}|st        j                  d|fdt         |f      dt        j                         v st        j
                  t               rt        j                  t               ndt        j                  |      dz  }dd|iz  }t        t        j                  |            dx}}t        j                  dg	      }|j                  }d}||u }|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)u?   crawldir 미지정 시 Spider.crawldir이 None이어야 한다.Nr$   r&   r
   r'   r*   r+   rL   r   r   )z0%(py2)s
{%(py2)s = %(py0)s.crawldir
} is %(py5)sr   r   r   r3   )r
   r6   r7   r8   r9   r:   r;   r<   r=   r   r]  r   s	            r   test_crawldir_none_by_defaultz7TestCheckpointIntegration.test_crawldir_none_by_defaultg  s     )-, ,,,, ,,,,,, ,,, ,,,,,,,,,,"22?T>UV&$&$&&&&$&&&&&&v&&&v&&&&&&$&&&&&&&r   c                 .   d}t         |u}|st        j                  d|fdt         |f      dt        j                         v st        j
                  t               rt        j                  t               ndt        j                  |      dz  }dd|iz  }t        t        j                  |            dx}}t        j                  dg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)uD   interval 파라미터가 _interval 속성에 반영되어야 한다.Nr$   r&   r
   r'   r*   r+   rL   g     @)r   intervalr,   z1%(py2)s
{%(py2)s = %(py0)s._interval
} == %(py5)sr   r   r   r3   r
   r6   r7   r8   r9   r:   r;   r<   r=   r   	_intervalr   s	            r   test_checkpoint_interval_setz6TestCheckpointIntegration.test_checkpoint_interval_setn  s     )-, ,,,, ,,,,,, ,,, ,,,,,,,,,,"22-.
 (5(5((((5((((((v(((v((((((5(((((((r   c                 ,   d}t         |u}|st        j                  d|fdt         |f      dt        j                         v st        j
                  t               rt        j                  t               ndt        j                  |      dz  }dd|iz  }t        t        j                  |            dx}}t        j                  dg	      }|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)u,   interval 기본값은 300.0이어야 한다.Nr$   r&   r
   r'   r*   r+   rL   r   g     r@r,   rc  r   r   r   r3   rd  r   s	            r    test_checkpoint_interval_defaultz:TestCheckpointIntegration.test_checkpoint_interval_defaultx  s     )-, ,,,, ,,,,,, ,,, ,,,,,,,,,,"22?T>UV(5(5((((5((((((v(((v((((((5(((((((r   r   )	r   r   r   r   r   r^  r`  rf  rh  rp   r   r   rZ  rZ  X  sS    0	/ 	/ ' ' ) ) ) )r   rZ  )rL   rM   )1r   builtinsr8   _pytest.assertion.rewrite	assertionrewriter6   r   r   sysr   pathlibr   typesr   typingr   r   unittest.mockr   r   r	   pytestr   insertr   __file__parentr
   __annotations__r   ModuleNotFoundError_MISSINGmarkskipifr   r   r   HTML_EMPTY_ITEMSintr   r   r    r"   r   r   r  r6  rZ  rp   r   r   <module>r}     sb  
    
      5 5  3tH~,,334 5 +/ 8J' .	0 $;;%%U &  (

	  %
	  		" s tCy c+ c+VF2 F2\q qrT0 T0xL- L-h%) %)s  		s   
D DD