§
    ¹¿jÒ3  ã                  ó–  — d Z ddlm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mZ ddlmZmZ ddlZddlmZ ddlmZ ddlmZ  ej        d	¬
¦  «        dd„¦   «         Z ej        d	¬
¦  «        dd„¦   «         Zej        dd„¦   «         Z G d„ d¦  «        Z G d„ d¦  «        Z  G d„ d¦  «        Z! G d„ d¦  «        Z"dS )zÙ
Adversarial Stress Test Suite for FreeExile 30 Map Styles Database & Service.
Verifies WAL concurrency, boundary edge cases, SQL injection immunity,
schema CHECK constraints, and missing/corrupted database recovery.
é    )ÚannotationsN)ÚPath)Ú	GeneratorÚList)Úinit_db©ÚMapStyleService)ÚMapStyleDefinitionÚmodule)ÚscopeÚreturnr   c                 óx   — t          t          ¦  «                             ¦   «         j        j        j        dz  dz  S )z,Return canonical path to data/map_styles.db.Údataúmap_styles.db)r   Ú__file__ÚresolveÚparent© ó    ú?C:\Projects\FreeExile\tests\unit\test_map_styles_adversarial.pyÚcanonical_db_pathr      s/   € õ •‰>Œ>×!Ò!Ñ#Ô#Ô*Ô1Ô8¸6ÑAÀOÑSÐSr   r   r	   c                ó"   — t          | ¬¦  «        S )z0Provide service connected to canonical database.©Údb_pathr   )r   s    r   Úservicer      s   € õ Ð#4Ð5Ñ5Ô5Ð5r   úGenerator[str, None, None]c               #  ó¨   K  — t          j        d¬¦  «        } t          j                             | d¦  «        }|V — t          j        | d¬¦  «         dS )zLProvide isolated temporary directory and database path for mutation testing.Úfe_adv_test_©Úprefixzisolated_map_styles.dbT©Úignore_errorsN)ÚtempfileÚmkdtempÚosÚpathÚjoinÚshutilÚrmtree)ÚtmpdirÚdb_files     r   Úisolated_temp_dbr,   #   sU   è è € õ Ô ^Ð4Ñ4Ô4€FÝŒg�lŠl˜6Ð#;Ñ<Ô<€GØ
€M€M€Må
„M�&¨Ð-Ñ-Ô-Ð-Ð-Ð-r   c                  ó*   — e Zd ZdZdd„Zdd	„Zdd
„ZdS )ÚTestMapStyleWALConcurrencyzFAdversarial testing of SQLite WAL mode and multi-threaded concurrency.r   r	   r   ÚNonec                ó   ‡‡‡— dˆfd„Št           j                             d¬¦  «        5 Šˆˆfd„t          d	¦  «        D ¦   «         }d
„ t           j                             |¦  «        D ¦   «         }ddd¦  «         n# 1 swxY w Y   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  }dd|iz  }t          t          j        |¦  «        ¦  «        ‚dx}x}}d„ |D ¦   «         }	t          |	¦  «        }
|
s•d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}	}
dS )zA50 worker threads querying styles, tiles, and props concurrently.Ú	worker_idÚintr   Úboolc                óÖ  •— | dz  dz   }‰                      |¦  «        }g }d }||u}|}|r|j        }||k    }|}|�s–t          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  }
|                     |
¦  «         |rÉt          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          j	        |d¦  «        i z  }dd|iz  }t          t          j        |¦  «        ¦  «        ‚d x}x}x}x}x}}‰                     |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        |¦  «        dœz  }dd|iz  }t          t          j        |¦  «        ¦  «        ‚d x}x}}‰                     |j        d¦  «        }g }d }||u}|}|r|j        }d}||k    }|}|�skt          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  }
|                     |
¦  «         |ržt          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          j	        |d¦  «        i z  }dd|iz  }t          t          j        |¦  «        ¦  «        ‚d x}x}x}x}x}x}}‰                     |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        |¦  «        dœz  }dd|iz  }t          t          j        |¦  «        ¦  «        ‚d x}x}}d$S )%Né   é   ©úis not)z%(py2)s is not %(py5)sÚs)Úpy2Úpy5z%(py7)sÚpy7©ú==)z5%(py11)s
{%(py11)s = %(py9)s.biome_code
} == %(py13)sÚcode)Úpy9Úpy11Úpy13z%(py15)sÚpy15r   zassert %(py18)sÚpy18é   ©z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} == %(py6)sÚlenÚtiles©Úpy0Úpy1Úpy3Úpy6úassert %(py8)sÚpy8Útile)z4%(py11)s
{%(py11)s = %(py9)s.tile_code
} == %(py14)s)r@   rA   Úpy14z%(py16)sÚpy16zassert %(py19)sÚpy19é   )ú>=)z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} >= %(py6)sÚpropsT)Úget_style_by_codeÚ
biome_codeÚ
@pytest_arÚ_call_reprcompareÚ@py_builtinsÚlocalsÚ_should_repr_global_nameÚ	_safereprÚappendÚ_format_boolopÚAssertionErrorÚ_format_explanationÚget_tiles_for_styleÚstyle_idrG   Úget_tile_mappingÚ	tile_codeÚget_props_for_style)r1   r?   r9   Ú@py_assert1Ú@py_assert4Ú@py_assert3Ú@py_assert0Ú@py_assert10Ú@py_assert12Ú@py_format6Ú@py_format8Ú@py_format14Ú@py_format16Ú@py_format17Ú@py_format19rH   Ú@py_assert2Ú@py_assert5Ú@py_format7Ú@py_format9rP   Ú@py_assert13Ú@py_format15Ú@py_format18Ú@py_format20rV   r   s                             €r   Úreader_taskzSTestMapStyleWALConcurrency.test_high_volume_concurrent_readers.<locals>.reader_task2   s¹  ø€ Ø ‘N aÑ'ˆDØ×)Ò)¨$Ñ/Ô/ˆAØ9Ð9˜DÐ9�1˜D�=Ð9Ð9Ð9Ð9Ð9 Q¤\Ð9 \°TÒ%9Ð9Ð9Ð9Ð9Ñ9Õ9Ô9Ð9Ð9Ð9Ð9�1˜DÐ9Ñ9Ô9Ð9Õ9Ô9Ñ9Ô9Ð9Ð9Õ9Ô9�1Ñ9Ô9Ð9Õ9Ô9�1Ñ9Ô9Ð9Ð9Õ9Ô9˜DÑ9Ô9Ð9Ð9Ñ9Ð9Ð9Ð9Ð9Ð9Ñ9Ð9Ð9×9Ò9Ð9Ñ9Ô9Ð9Ð9Ð9Õ9Ô9Ð9Ð9Ð9Ð9 \°TÐ9Ñ9Ô9Ð9Õ9Ô9Ñ9Ô9Ð9Ð9Õ9Ô9 QÑ9Ô9Ð9Õ9Ô9 QÑ9Ô9Ð9Ð9Õ9Ô9 \Ñ9Ô9Ð9Õ9Ô9Ñ9Ô9Ð9Ð9Õ9Ô9°TÑ9Ô9Ð9Õ9Ô9°TÑ9Ô9Ð9Ð9Ð9Ð9Ñ9Ð9Ð9Ð9Ð9Ð9Ñ9Ð9Ð9×9Ò9Ð9Ñ9Ô9Ð9Õ9Ô9Ð9Ð9Ñ9Ô9Ð9Ñ9Ð9Ð9Ð9Ð9Ð9Ñ9Ð9Õ9Õ9Ô9Ð9Ñ9Ô9Ñ9Ô9Ð9Ð9Ð9Ð9Ð9Ð9Ð9Ð9Ð9Ð9Ð9Ð9Ð9Ø×/Ò/°´
Ñ;Ô;ˆEÝ�u‘:”:Ð# Ð#�: Ò#Ð#Ð#Ð#Õ#Ô#Ð#Ð#Ð#Ð#�: Ð#Ñ#Ô#Ð#Õ#Ô#Ñ#Ô#Ð#Ð#Õ#Ô#•3Ñ#Ô#Ð#Õ#Ô#•3Ñ#Ô#Ð#Ð#Ð#Õ#Ô#Ñ#Ô#Ð#Ð#Õ#Ô#�uÑ#Ô#Ð#Õ#Ô#�uÑ#Ô#Ð#Ð#Õ#Ô#�:Ñ#Ô#Õ#Ô# Ñ#Ô#Ð#Ð#Ñ#Ð#Ð#Ð#Ð#Ð#Ñ#Ð#Õ#Õ#Ô#Ð#Ñ#Ô#Ñ#Ô#Ð#Ð#Ð#Ð#Ð#Ð#Ð#Ø×+Ò+¨A¬J¸Ñ:Ô:ˆDØ;Ð;˜tÐ;�4˜tÐ#Ð;Ð;Ð;Ð;Ð;¨¬Ð;¸!Ð;¨¸!Ò(;Ð;Ð;Ð;Ð;Ñ;Õ;Ô;Ð;Ð;Ð;Ð;�4˜tÐ;Ñ;Ô;Ð;Õ;Ô;Ñ;Ô;Ð;Ð;Õ;Ô;�4Ñ;Ô;Ð;Õ;Ô;�4Ñ;Ô;Ð;Ð;Õ;Ô;˜tÑ;Ô;Ð;Ð;Ñ;Ð;Ð;Ð;Ð;Ð;Ñ;Ð;Ð;×;Ò;Ð;Ñ;Ô;Ð;Ð;Ð;Õ;Ô;Ð;Ð;Ð;Ð;¨¸!Ð;Ñ;Ô;Ð;Õ;Ô;Ñ;Ô;Ð;Ð;Õ;Ô;¨Ñ;Ô;Ð;Õ;Ô;¨Ñ;Ô;Ð;Ð;Õ;Ô;¨Ñ;Ô;Õ;Ô;¸!Ñ;Ô;Ð;Ð;Ñ;Ð;Ð;Ð;Ð;Ð;Ñ;Ð;Ð;×;Ò;Ð;Ñ;Ô;Ð;Õ;Ô;Ð;Ð;Ñ;Ô;Ð;Ñ;Ð;Ð;Ð;Ð;Ð;Ñ;Ð;Õ;Õ;Ô;Ð;Ñ;Ô;Ñ;Ô;Ð;Ð;Ð;Ð;Ð;Ð;Ð;Ð;Ð;Ð;Ð;Ð;Ð;Ð;Ð;Ø×/Ò/°´
Ñ;Ô;ˆEÝ�u‘:”:Ð" Ð"�: ’?Ð"Ð"Ð"Õ"Ô"Ð"Ð"Ð"Ð"�: Ð"Ñ"Ô"Ð"Õ"Ô"Ñ"Ô"Ð"Ð"Õ"Ô"•3Ñ"Ô"Ð"Õ"Ô"•3Ñ"Ô"Ð"Ð"Ð"Õ"Ô"Ñ"Ô"Ð"Ð"Õ"Ô"�uÑ"Ô"Ð"Õ"Ô"�uÑ"Ô"Ð"Ð"Õ"Ô"�:Ñ"Ô"Õ"Ô" Ñ"Ô"Ð"Ð"Ñ"Ð"Ð"Ð"Ð"Ð"Ñ"Ð"Õ"Õ"Ô"Ð"Ñ"Ô"Ñ"Ô"Ð"Ð"Ð"Ð"Ð"Ð"Ð"Ø�4r   é2   ©Úmax_workersc                ó<   •— g | ]}‰                      ‰|¦  «        ‘ŒS r   ©Úsubmit©Ú.0ÚiÚpoolr|   s     €€r   ú
<listcomp>zRTestMapStyleWALConcurrency.test_high_volume_concurrent_readers.<locals>.<listcomp>?   s'   ø€ ÐGÐGÐG°q�t—{’{ ;°Ñ2Ô2ÐGÐGÐGr   éú   c                ó6   — g | ]}|                      ¦   «         ‘ŒS r   ©Úresult©r„   Úfs     r   r‡   zRTestMapStyleWALConcurrency.test_high_volume_concurrent_readers.<locals>.<listcomp>@   s    € ÐTÐTÐT a�q—x’x‘z”zÐTÐTÐTr   Nr=   rF   rG   ÚresultsrI   rN   rO   c              3  ó   K  — | ]}|d u V — Œ	dS ©TNr   ©r„   Úrs     r   ú	<genexpr>zQTestMapStyleWALConcurrency.test_high_volume_concurrent_readers.<locals>.<genexpr>C   ó&   è è € Ð.Ð. �1˜�9Ð.Ð.Ð.Ð.Ð.Ð.r   ú,assert %(py4)s
{%(py4)s = %(py0)s(%(py2)s)
}Úall©rJ   r:   Úpy4)r1   r2   r   r3   )Ú
concurrentÚfuturesÚThreadPoolExecutorÚrangeÚas_completedrG   rY   rZ   r[   r\   r]   r^   ra   rb   r–   )Úselfr   rš   rŽ   rt   ru   ri   rv   rw   rh   rj   Ú@py_format5r†   r|   s    `          @@r   Ú#test_high_volume_concurrent_readersz>TestMapStyleWALConcurrency.test_high_volume_concurrent_readers0   sÀ  øøø€ ð
	ð 
	ð 
	ð 
	ð 
	ð 
	õ Ô×2Ò2¸rÐ2ÑBÔBð 	UÀdØGÐGÐGÐGÐG½EÀ#¹J¼JÐGÑGÔGˆGØTÐT­:Ô+=×+JÒ+JÈ7Ñ+SÔ+SÐTÑTÔTˆGð	Uð 	Uð 	Uñ 	Uô 	Uð 	Uð 	Uð 	Uð 	Uð 	Uð 	Uøøøð 	Uð 	Uð 	Uð 	Uõ �7‰|Œ|Ð"˜sÐ"ˆ|˜sÒ"Ð"Ð"Ð"Õ"Ô"Ð"Ð"Ð"Ð"ˆ|˜sÐ"Ñ"Ô"Ð"Õ"Ô"Ñ"Ô"Ð"Ð"Õ"Ô"�sÑ"Ô"Ð"Õ"Ô"�sÑ"Ô"Ð"Ð"Ð"Õ"Ô"Ñ"Ô"Ð"Ð"Õ"Ô"�7Ñ"Ô"Ð"Õ"Ô"�7Ñ"Ô"Ð"Ð"Õ"Ô"ˆ|Ñ"Ô"Õ"Ô"˜sÑ"Ô"Ð"Ð"Ñ"Ð"Ð"Ð"Ð"Ð"Ñ"Ð"Õ"Õ"Ô"Ð"Ñ"Ô"Ñ"Ô"Ð"Ð"Ð"Ð"Ð"Ð"Ð"Ø.Ð. gÐ.Ñ.Ô.Ð.�sÐ.Ñ.Ô.Ð.Ð.Ð.Ð.Ð.Õ.Ô.Ñ.Ô.Ð.Ð.Õ.Ô.�sÑ.Ô.Ð.Õ.Ô.�sÑ.Ô.Ð.Ð.Õ.Ô.Ð.Ñ.Ô.Õ.Ô.Ð.Ñ.Ô.Ð.Ð.Ñ.Ð.Õ.Õ.Ô.Ð.Ñ.Ô.Ñ.Ô.Ð.Ð.Ð.Ð.Ð.Ð.Ð.s   ªAA<Á<B ÂB r,   Ústrc                ó  ‡‡‡‡— t          |¬¦  «        Šdˆfd„Šdˆfd„Št          j                             d¬	¦  «        5 Šˆˆfd
„t	          d¦  «        D ¦   «         }ˆˆfd„t	          d¦  «        D ¦   «         }||z   }d„ t          j                             |¦  «        D ¦   «         }ddd¦  «         n# 1 swxY w Y   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  }	dd|	iz  }
t          t          j        |
¦  «        ¦  «        ‚dx}x}}d„ |D ¦   «         }t          |¦  «        }|s•d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}}dS )zUConcurrent readers querying database while writers execute seed_database(force=True).r   r   r3   c                 ó¢  •— t          d¦  «        D ]½} ‰                     d¬¦  «        }d}||k    }|s—t          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S )NrT   T)Úforcer5   r=   ©z%(py0)s == %(py3)sÚcnt©rJ   rL   úassert %(py5)sr;   )
rœ   Úseed_databaserY   rZ   r[   r\   r]   r^   ra   rb   )Ú_r¦   rt   rh   Ú@py_format4rn   Úmut_services         €r   Úwriter_taskzXTestMapStyleWALConcurrency.test_concurrent_read_during_force_reseed.<locals>.writer_taskI   s÷   ø€ Ý˜1‘X”Xð !ð !�Ø!×/Ò/°dÐ/Ñ;Ô;�Ø Ð �s˜b’yÐ Ð Ð Õ Ô Ð Ð Ð Ð �s˜bÐ Ñ Ô Ð Õ Ô Ñ Ô Ð Ð Õ Ô �sÑ Ô Ð Õ Ô �sÑ Ô Ð Ð Õ Ô ˜bÑ Ô Ð Ð Ñ Ð Ð Ð Ð Ð Ñ Ð Õ Õ Ô Ð Ñ Ô Ñ Ô Ð Ð Ð Ð Ð Ð Ø�4r   Úidxr2   c                ó  •— t          d¦  «        D �]ì}‰                     | dz  dz   ¦  «        }d }||u}|s—t          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}}‰ 
                    |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        |¦  «        dœz  }
dd|
iz  }t          t          j	        |¦  «        ¦  «        ‚d x}x}	}�ŒîdS )Né   r5   r6   r7   )z%(py0)s is not %(py3)sÚstyler§   r¨   r;   rE   r=   rF   rG   rH   rI   rN   rO   T)rœ   rW   rY   rZ   r[   r\   r]   r^   ra   rb   rc   rd   rG   )r®   rª   r±   rt   rh   r«   rn   rH   ru   ri   rv   rw   r¬   s               €r   r|   zXTestMapStyleWALConcurrency.test_concurrent_read_during_force_reseed.<locals>.reader_taskO   s-  ø€ Ý˜2‘Y”Yð (ñ (�Ø#×5Ò5°s¸R±xÀ1±nÑEÔE�Ø$(Ð(�u DÐ(Ð(Ð(Ð(Õ(Ô(Ð(Ð(Ð(Ð(�u DÐ(Ñ(Ô(Ð(Õ(Ô(Ñ(Ô(Ð(Ð(Õ(Ô(�uÑ(Ô(Ð(Õ(Ô(�uÑ(Ô(Ð(Ð(Õ(Ô( DÑ(Ô(Ð(Ð(Ñ(Ð(Ð(Ð(Ð(Ð(Ñ(Ð(Õ(Õ(Ô(Ð(Ñ(Ô(Ñ(Ô(Ð(Ð(Ð(Ð(Ð(Ø#×7Ò7¸¼ÑGÔG�Ý˜5‘z”zÐ' RÐ'�z RÒ'Ð'Ð'Ð'Õ'Ô'Ð'Ð'Ð'Ð'�z RÐ'Ñ'Ô'Ð'Õ'Ô'Ñ'Ô'Ð'Ð'Õ'Ô'•sÑ'Ô'Ð'Õ'Ô'•sÑ'Ô'Ð'Ð'Ð'Õ'Ô'Ñ'Ô'Ð'Ð'Õ'Ô'˜5Ñ'Ô'Ð'Õ'Ô'˜5Ñ'Ô'Ð'Ð'Õ'Ô'�zÑ'Ô'Õ'Ô' RÑ'Ô'Ð'Ð'Ñ'Ð'Ð'Ð'Ð'Ð'Ñ'Ð'Õ'Õ'Ô'Ð'Ñ'Ô'Ñ'Ô'Ð'Ð'Ð'Ð'Ð'Ð'Ð'Ñ'Ø�4r   rE   r~   c                ó:   •— g | ]}‰                      ‰¦  «        ‘ŒS r   r�   )r„   rª   r†   r­   s     €€r   r‡   zWTestMapStyleWALConcurrency.test_concurrent_read_during_force_reseed.<locals>.<listcomp>X   s%   ø€ ÐHÐHÐH¸!˜TŸ[š[¨Ñ5Ô5ÐHÐHÐHr   é   c                ó<   •— g | ]}‰                      ‰|¦  «        ‘ŒS r   r�   rƒ   s     €€r   r‡   zWTestMapStyleWALConcurrency.test_concurrent_read_during_force_reseed.<locals>.<listcomp>Y   s'   ø€ ÐKÐKÐK¸A˜DŸKšK¨°QÑ7Ô7ÐKÐKÐKr   é   c                ó6   — g | ]}|                      ¦   «         ‘ŒS r   rŠ   rŒ   s     r   r‡   zWTestMapStyleWALConcurrency.test_concurrent_read_during_force_reseed.<locals>.<listcomp>[   s    € ÐXÐXÐX a�q—x’x‘z”zÐXÐXÐXr   Nr=   rF   rG   rŽ   rI   rN   rO   c              3  ó   K  — | ]}|d u V — Œ	dS r�   r   r‘   s     r   r“   zVTestMapStyleWALConcurrency.test_concurrent_read_during_force_reseed.<locals>.<genexpr>^   r”   r   r•   r–   r—   )r   r3   )r®   r2   r   r3   )r	   r™   rš   r›   rœ   r�   rG   rY   rZ   r[   r\   r]   r^   ra   rb   r–   )rž   r,   Úwrite_futuresÚread_futuresÚall_futuresrŽ   rt   ru   ri   rv   rw   rh   rj   rŸ   r¬   r†   r|   r­   s                 @@@@r   Ú(test_concurrent_read_during_force_reseedzCTestMapStyleWALConcurrency.test_concurrent_read_during_force_reseedE   s  øøøø€ å%Ð.>Ð?Ñ?Ô?ˆð	ð 	ð 	ð 	ð 	ð 	ð	ð 	ð 	ð 	ð 	ð 	õ Ô×2Ò2¸rÐ2ÑBÔBð 	YÀdØHÐHÐHÐHÐH½uÀQ¹x¼xÐHÑHÔHˆMØKÐKÐKÐKÐKÅÀrÁÄÐKÑKÔKˆLØ'¨,Ñ6ˆKØXÐX­:Ô+=×+JÒ+JÈ;Ñ+WÔ+WÐXÑXÔXˆGð		Yð 	Yð 	Yñ 	Yô 	Yð 	Yð 	Yð 	Yð 	Yð 	Yð 	Yøøøð 	Yð 	Yð 	Yð 	Yõ �7‰|Œ|Ð!˜rÐ!ˆ|˜rÒ!Ð!Ð!Ð!Õ!Ô!Ð!Ð!Ð!Ð!ˆ|˜rÐ!Ñ!Ô!Ð!Õ!Ô!Ñ!Ô!Ð!Ð!Õ!Ô!�sÑ!Ô!Ð!Õ!Ô!�sÑ!Ô!Ð!Ð!Ð!Õ!Ô!Ñ!Ô!Ð!Ð!Õ!Ô!�7Ñ!Ô!Ð!Õ!Ô!�7Ñ!Ô!Ð!Ð!Õ!Ô!ˆ|Ñ!Ô!Õ!Ô!˜rÑ!Ô!Ð!Ð!Ñ!Ð!Ð!Ð!Ð!Ð!Ñ!Ð!Õ!Õ!Ô!Ð!Ñ!Ô!Ñ!Ô!Ð!Ð!Ð!Ð!Ð!Ð!Ð!Ø.Ð. gÐ.Ñ.Ô.Ð.�sÐ.Ñ.Ô.Ð.Ð.Ð.Ð.Ð.Õ.Ô.Ñ.Ô.Ð.Ð.Õ.Ô.�sÑ.Ô.Ð.Õ.Ô.�sÑ.Ô.Ð.Ð.Õ.Ô.Ð.Ñ.Ô.Õ.Ô.Ð.Ñ.Ô.Ð.Ð.Ñ.Ð.Õ.Õ.Ô.Ð.Ñ.Ô.Ñ.Ô.Ð.Ð.Ð.Ð.Ð.Ð.Ð.s   ÁA'B4Â4B8Â;B8c           	     óÎ  ‡— t          d¬¦  «        Š‰j        }d} ||¦  «        }d}||u}|sÐt          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ˆfd„}t          j                             d¬¦  «        5 }	|	                     |¦  «        }
t          j        t           j        ¦  «        5 }|
                     ¦   «          ddd¦  «         n# 1 swxY w Y   d}|j        }t)          |¦  «        }||v }|�st          j        d|fd||f¦  «        t          j        |¦  «        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}x}}ddd¦  «         n# 1 swxY w Y   ‰                     ¦   «          dS )zJIn-memory SQLite connection is bound to creation thread unless configured.z:memory:r   r6   Nr7   )z[%(py6)s
{%(py6)s = %(py2)s
{%(py2)s = %(py0)s.get_style_by_code
}(%(py4)s)
} is not %(py9)sÚmem_service)rJ   r:   r˜   rM   r@   zassert %(py11)srA   r   r/   c                 ó2   •— ‰                       d¦  «         d S )Nr6   )rW   )r½   s   €r   Úcross_thread_callz\TestMapStyleWALConcurrency.test_in_memory_service_thread_boundary.<locals>.cross_thread_calle   s   ø€ Ø×)Ò)¨!Ñ,Ô,Ð,Ð,Ð,r   r~   zGSQLite objects created in a thread can only be used in that same thread)Úin)zK%(py1)s in %(py8)s
{%(py8)s = %(py3)s(%(py6)s
{%(py6)s = %(py4)s.value
})
}r¡   Úexc_info)rK   rL   r˜   rM   rO   úassert %(py10)sÚpy10©r   r/   )r	   rW   rY   rZ   r[   r\   r]   r^   ra   rb   r™   rš   r›   r‚   ÚpytestÚraisesÚsqlite3ÚProgrammingErrorr‹   Úvaluer¡   Úclose)rž   rh   rj   ru   Ú@py_assert8Ú@py_assert7Ú@py_format10Ú@py_format12r¿   r†   ÚfuturerÁ   rk   rt   rw   Ú@py_format11r½   s                   @r   Ú&test_in_memory_service_thread_boundaryzATestMapStyleWALConcurrency.test_in_memory_service_thread_boundary`   s´  ø€ å%¨jÐ9Ñ9Ô9ˆØÔ,Ð;¨QÐ;Ð,Ð,¨QÑ/Ô/Ð;°tÐ;Ð/°tÐ;Ð;Ð;Ð;Õ;Ô;Ð;Ð;Ð;Ð;Ð/°tÐ;Ñ;Ô;Ð;Õ;Ô;Ñ;Ô;Ð;Ð;Õ;Ô;ˆ{Ñ;Ô;Ð;Õ;Ô;ˆ{Ñ;Ô;Ð;Ð;Õ;Ô;Ð,Ñ;Ô;Õ;Ô;¨QÑ;Ô;Õ;Ô;Ð/Ñ;Ô;Õ;Ô;°tÑ;Ô;Ð;Ð;Ñ;Ð;Ð;Ð;Ð;Ð;Ñ;Ð;Õ;Õ;Ô;Ð;Ñ;Ô;Ñ;Ô;Ð;Ð;Ð;Ð;Ð;Ð;Ð;Ð;Ð;Ð;Ð;ð	-ð 	-ð 	-ð 	-ð 	-ð 	-õ Ô×2Ò2¸qÐ2ÑAÔAð 	tÀTØ—[’[Ð!2Ñ3Ô3ˆFÝ”�wÔ7Ñ8Ô8ð  ¸HØ—’‘”�ð ð  ð  ñ  ô  ð  ð  ð  ð  ð  ð  øøøð  ð  ð  ð  à\ÐsÐdlÔdrÐsÕ`cÐdrÑ`sÔ`sÐsÐ\Ð`sÐsÐsÐsÑsÕsÔsÐsÐsÐsÐsÐ\Ð`sÐsÑsÔsÕsÔsÐ\ÑsÔsÐsÕsÔsÑsÔsÐsÐsÕsÔsÕ`cÑsÔsÐsÕsÔsÕ`cÑsÔsÐsÐsÐsÕsÔsÑsÔsÐsÐsÕsÔsÐdlÑsÔsÐsÕsÔsÐdlÑsÔsÐsÐsÕsÔsÐdrÑsÔsÕsÔsÐ`sÑsÔsÐsÐsÑsÐsÐsÐsÐsÐsÑsÐsÕsÕsÔsÐsÑsÔsÑsÔsÐsÐsÐsÐsÐsÐsÐsÐsÐsð		tð 	tð 	tñ 	tô 	tð 	tð 	tð 	tð 	tð 	tð 	tøøøð 	tð 	tð 	tð 	tð
 	×ÒÑÔÐÐÐs7   Ä.4KÅ"FÅ7KÆF	ÆKÆ
F	ÆD/KËK
ËK
N©r   r	   r   r/   )r,   r¡   r   r/   rÄ   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r    r»   rÑ   r   r   r   r.   r.   -   sV   € € € € € ØPÐPð/ð /ð /ð /ð*/ð /ð /ð /ð6ð ð ð ð ð r   r.   c                  ód  — e Zd ZdZej                             dg d¢¦  «        dd	„¦   «         Zej                             d
g d¢¦  «        dd„¦   «         Zej                             dddddg i  e	¦   «         g¦  «        dd„¦   «         Z
ej                             dg d¢¦  «        dd„¦   «         ZdS )Ú"TestMapStyleEdgeCasesAndBoundarieszIStress-test out-of-range boundaries, invalid types, and malformed inputs.Úinvalid_code)r   éÿÿÿÿéüÿÿé   é    éd   éÿ   é   éç  éÿÿÿi   €r   r	   r2   r   r/   c                ó@  — |j         } ||¦  «        }d}||u }|sût          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t          j        |¦  «        t          j        |¦  «        dœz  }dd|iz  }t          t          j        |¦  «        ¦  «        ‚dx}x}x}}dS )	zBAll out-of-range integer biome codes return None without crashing.N©Úis)zW%(py5)s
{%(py5)s = %(py2)s
{%(py2)s = %(py0)s.get_style_by_code
}(%(py3)s)
} is %(py8)sr   rÙ   ©rJ   r:   rL   r;   rO   rÂ   rÃ   )	rW   rY   rZ   r[   r\   r]   r^   ra   rb   )	rž   r   rÙ   rh   ri   rÌ   Ú@py_assert6rw   rÐ   s	            r   Ú)test_out_of_range_biome_codes_return_nonezLTestMapStyleEdgeCasesAndBoundaries.test_out_of_range_biome_codes_return_nones   sK  € ð Ô(Ð>Ð(Ð(¨Ñ6Ô6Ð>¸$Ð>Ð6¸$Ð>Ð>Ð>Ð>Õ>Ô>Ð>Ð>Ð>Ð>Ð6¸$Ð>Ñ>Ô>Ð>Õ>Ô>Ñ>Ô>Ð>Ð>Õ>Ô>ˆwÑ>Ô>Ð>Õ>Ô>ˆwÑ>Ô>Ð>Ð>Õ>Ô>Ð(Ñ>Ô>Ð>Õ>Ô>Ñ>Ô>Ð>Ð>Õ>Ô>¨Ñ>Ô>Ð>Õ>Ô>¨Ñ>Ô>Ð>Ð>Õ>Ô>Ð6Ñ>Ô>Õ>Ô>¸$Ñ>Ô>Ð>Ð>Ñ>Ð>Ð>Ð>Ð>Ð>Ñ>Ð>Õ>Õ>Ô>Ð>Ñ>Ô>Ñ>Ô>Ð>Ð>Ð>Ð>Ð>Ð>Ð>Ð>Ð>Ð>Ð>r   Úinvalid_tile)	rÚ   iöÿÿÿrÛ   rE   é   r}   rÞ   rá   râ   c                óx  — |                      d|¦  «        }d}||u }|s—t          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S )	zAAll out-of-range integer tile codes return None without crashing.ÚSTY_01_HOANG_MANG_CO_LONrä   ©z%(py0)s is %(py3)sÚmappingr§   r¨   r;   )	re   rY   rZ   r[   r\   r]   r^   ra   rb   )rž   r   ré   rî   rt   rh   r«   rn   s           r   Ú(test_out_of_range_tile_codes_return_nonezKTestMapStyleEdgeCasesAndBoundaries.test_out_of_range_tile_codes_return_nonex   sá   € ð ×*Ò*Ð+DÀlÑSÔSˆØÐˆw˜$ˆÐÐÐÕÔÐÐÐÐˆw˜$ÐÑÔÐÕÔÑÔÐÐÕÔˆwÑÔÐÕÔˆwÑÔÐÐÕÔ˜$ÑÔÐÐÑÐÐÐÐÐÑÐÕÕÔÐÑÔÑÔÐÐÐÐÐÐÐr   Útype_mismatchÚ1g      ð?g      ø?NÚobjectc                óÐ  — 	 |                      |¦  «        }|��$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S dS # t          j        t          j        t          f$ r Y dS w xY w)z\Non-integer biome code inputs either return None or raise standard Python errors gracefully.Nz5assert %(py4)s
{%(py4)s = %(py0)s(%(py1)s, %(py2)s)
}Ú
isinstanceÚresr
   )rJ   rK   r:   r˜   )rW   rô   r
   r[   r\   rY   r]   r^   ra   rb   rÇ   ÚInterfaceErrorrÈ   Ú	TypeError)rž   r   rð   rõ   rj   rŸ   s         r   Ú.test_biome_code_type_mismatches_handled_safelyzQTestMapStyleEdgeCasesAndBoundaries.test_biome_code_type_mismatches_handled_safely~   sa  € ð	Ø×+Ò+¨MÑ:Ô:ˆCà‰Ý! #Õ'9Ñ:Ô:Ð:Ð:Ñ:Ð:Ð:Õ:Ô:Ñ:Ô:Ð:Ð:Õ:Ô:•zÑ:Ô:Ð:Õ:Ô:•zÑ:Ô:Ð:Ð:Ð:Õ:Ô:Ñ:Ô:Ð:Ð:Õ:Ô: #Ñ:Ô:Ð:Õ:Ô: #Ñ:Ô:Ð:Ð:Ð:Õ:Ô:Ñ:Ô:Ð:Ð:Õ:Ô:Õ'9Ñ:Ô:Ð:Õ:Ô:Õ'9Ñ:Ô:Ð:Ð:Õ:Ô:Ð:Ñ:Ô:Ð:Ð:Ñ:Ð:Õ:Õ:Ô:Ð:Ñ:Ô:Ñ:Ô:Ð:Ð:Ð:Ð:Ð:ð ˆøåÔ&­Ô(@Å)ÐLð 	ð 	ð 	ØˆDˆDð	øøøs   ‚D:E  Å !E%Å$E%Úbad_style_id)Ú z   z	
Ústy_01_lowercaseÚUNKNOWN_NONEXISTENTr¡   c           	     ó(	  — |j         } ||¦  «        }d}||u }|sût          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t          j        |¦  «        t          j        |¦  «        dœz  }dd|iz  }t          t          j        |¦  «        ¦  «        ‚dx}x}x}}|j	        } ||¦  «        }g }||k    }|sût          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t          j        |¦  «        t          j        |¦  «        dœz  }dd|iz  }t          t          j        |¦  «        ¦  «        ‚dx}x}x}}|j
        }d} |||¦  «        }d}	||	u }
|
�st          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t          j        |¦  «        t          j        |¦  «        t          j        |	¦  «        dœz  }dd|iz  }t          t          j        |¦  «        ¦  «        ‚dx}x}x}x}
}	|j        } ||¦  «        }g }||k    }|sût          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t          j        |¦  «        t          j        |¦  «        dœz  }dd|iz  }t          t          j        |¦  «        ¦  «        ‚dx}x}x}}dS )zJInvalid, empty, or uncanonical style_ids return None or empty collections.Nrä   )zO%(py5)s
{%(py5)s = %(py2)s
{%(py2)s = %(py0)s.get_style
}(%(py3)s)
} is %(py8)sr   rù   ræ   rÂ   rÃ   r=   )zY%(py5)s
{%(py5)s = %(py2)s
{%(py2)s = %(py0)s.get_tiles_for_style
}(%(py3)s)
} == %(py8)sr6   )z`%(py7)s
{%(py7)s = %(py2)s
{%(py2)s = %(py0)s.get_tile_mapping
}(%(py3)s, %(py5)s)
} is %(py10)s)rJ   r:   rL   r;   r<   rÃ   úassert %(py12)sÚpy12)zY%(py5)s
{%(py5)s = %(py2)s
{%(py2)s = %(py0)s.get_props_for_style
}(%(py3)s)
} == %(py8)s©Ú	get_stylerY   rZ   r[   r\   r]   r^   ra   rb   rc   re   rg   )rž   r   rù   rh   ri   rÌ   rç   rw   rÐ   Ú@py_assert9rË   Ú@py_format13s               r   Ú+test_invalid_style_ids_return_empty_or_nonezNTestMapStyleEdgeCasesAndBoundaries.test_invalid_style_ids_return_empty_or_none‰   s)  € ð Ô Ð6Ð Ð  Ñ.Ô.Ð6°$Ð6Ð.°$Ð6Ð6Ð6Ð6Õ6Ô6Ð6Ð6Ð6Ð6Ð.°$Ð6Ñ6Ô6Ð6Õ6Ô6Ñ6Ô6Ð6Ð6Õ6Ô6ˆwÑ6Ô6Ð6Õ6Ô6ˆwÑ6Ô6Ð6Ð6Õ6Ô6Ð Ñ6Ô6Ð6Õ6Ô6Ñ6Ô6Ð6Ð6Õ6Ô6 Ñ6Ô6Ð6Õ6Ô6 Ñ6Ô6Ð6Ð6Õ6Ô6Ð.Ñ6Ô6Õ6Ô6°$Ñ6Ô6Ð6Ð6Ñ6Ð6Ð6Ð6Ð6Ð6Ñ6Ð6Õ6Õ6Ô6Ð6Ñ6Ô6Ñ6Ô6Ð6Ð6Ð6Ð6Ð6Ð6Ð6Ð6Ð6ØÔ*Ð>Ð*Ð*¨<Ñ8Ô8Ð>¸BÐ>Ð8¸BÒ>Ð>Ð>Ð>Õ>Ô>Ð>Ð>Ð>Ð>Ð8¸BÐ>Ñ>Ô>Ð>Õ>Ô>Ñ>Ô>Ð>Ð>Õ>Ô>ˆwÑ>Ô>Ð>Õ>Ô>ˆwÑ>Ô>Ð>Ð>Õ>Ô>Ð*Ñ>Ô>Ð>Õ>Ô>Ñ>Ô>Ð>Ð>Õ>Ô>¨<Ñ>Ô>Ð>Õ>Ô>¨<Ñ>Ô>Ð>Ð>Õ>Ô>Ð8Ñ>Ô>Õ>Ô>¸BÑ>Ô>Ð>Ð>Ñ>Ð>Ð>Ð>Ð>Ð>Ñ>Ð>Õ>Õ>Ô>Ð>Ñ>Ô>Ñ>Ô>Ð>Ð>Ð>Ð>Ð>Ð>Ð>Ð>Ð>ØÔ'Ð@°aÐ@Ð'Ð'¨°aÑ8Ô8Ð@¸DÐ@Ð8¸DÐ@Ð@Ð@Ñ@Õ@Ô@Ð@Ð@Ð@Ð@Ð8¸DÐ@Ñ@Ô@Ð@Õ@Ô@Ñ@Ô@Ð@Ð@Õ@Ô@ˆwÑ@Ô@Ð@Õ@Ô@ˆwÑ@Ô@Ð@Ð@Õ@Ô@Ð'Ñ@Ô@Ð@Õ@Ô@Ñ@Ô@Ð@Ð@Õ@Ô@¨Ñ@Ô@Ð@Õ@Ô@¨Ñ@Ô@Ð@Ð@Õ@Ô@°aÑ@Ô@Õ@Ô@Ð8Ñ@Ô@Õ@Ô@¸DÑ@Ô@Ð@Ð@Ñ@Ð@Ð@Ð@Ð@Ð@Ñ@Ð@Õ@Õ@Ô@Ð@Ñ@Ô@Ñ@Ô@Ð@Ð@Ð@Ð@Ð@Ð@Ð@Ð@Ð@Ð@Ð@ØÔ*Ð>Ð*Ð*¨<Ñ8Ô8Ð>¸BÐ>Ð8¸BÒ>Ð>Ð>Ð>Õ>Ô>Ð>Ð>Ð>Ð>Ð8¸BÐ>Ñ>Ô>Ð>Õ>Ô>Ñ>Ô>Ð>Ð>Õ>Ô>ˆwÑ>Ô>Ð>Õ>Ô>ˆwÑ>Ô>Ð>Ð>Õ>Ô>Ð*Ñ>Ô>Ð>Õ>Ô>Ñ>Ô>Ð>Ð>Õ>Ô>¨<Ñ>Ô>Ð>Õ>Ô>¨<Ñ>Ô>Ð>Ð>Õ>Ô>Ð8Ñ>Ô>Õ>Ô>¸BÑ>Ô>Ð>Ð>Ñ>Ð>Ð>Ð>Ð>Ð>Ñ>Ð>Õ>Õ>Ô>Ð>Ñ>Ô>Ñ>Ô>Ð>Ð>Ð>Ð>Ð>Ð>Ð>Ð>Ð>Ð>Ð>r   )r   r	   rÙ   r2   r   r/   )r   r	   ré   r2   r   r/   )r   r	   rð   rò   r   r/   )r   r	   rù   r¡   r   r/   )rÓ   rÔ   rÕ   rÖ   rÅ   ÚmarkÚparametrizerè   rï   rò   rø   r  r   r   r   rØ   rØ   p   s  € € € € € ØSÐSà„[×Ò˜^Ð-iÐ-iÐ-iÑjÔjð?ð ?ð ?ñ kÔjð?ð „[×Ò˜^Ð-]Ð-]Ð-]Ñ^Ô^ðð ð ñ _Ô^ðð
 „[×Ò˜_¨s°C¸¸dÀBÈÈFÈFÉHÌHÐ.UÑVÔVðð ð ñ WÔVðð „[×Ò˜^Ð-kÐ-kÐ-kÑlÔlð?ð ?ð ?ñ mÔlð?ð ?ð ?r   rØ   c                  ó”   — e Zd ZdZdddddddd	d
ddddddddddz  dgZej                             de¦  «        dd„¦   «         Zd d„Z	dS )!Ú TestMapStyleSQLInjectionImmunityzCStress-test SQL injection attacks across all service query methods.z' OR '1'='1z'; DROP TABLE map_styles; --z!'; DROP TABLE map_style_tiles; --z!'; DROP TABLE map_style_props; --z#' UNION SELECT * FROM map_styles --z"STY_01_HOANG_MANG_CO_LO' OR '1'='1zadmin'--z' OR 1=1; --zSLEEP(5)z'; VACUUM; --zSTY_01' /* comment */z<script>alert('xss')</script>z' OR biome_code=1 --ú%rª   z&' AND (SELECT 1 FROM sqlite_master) --zSTY_01 _INJECTIONÚAi'  u   ðŸ�‰_LORE_STYLE_' OR 1=1;--Úpayloadr   r	   r¡   r   r/   c                óÐ  — |                      |¦  «        }d}||u }|s—t          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}}| 	                    |¦  «        }g }||k    }|s—t          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}|	|u }|s—t          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}}|                     |¦  «        }
g }|
|k    }|s—t          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S )zTVerify queries with SQL injection payloads safely return None/empty and preserve DB.Nrä   rí   rõ   r§   r¨   r;   r=   r¥   rH   r6   rP   rV   r   )rž   r   r  rõ   rt   rh   r«   rn   rH   rP   rV   s              r   Útest_sqli_payload_resistancez=TestMapStyleSQLInjectionImmunity.test_sqli_payload_resistance«   sb  € ð ×Ò Ñ(Ô(ˆØÐˆs�dˆ{ÐÐÐÕÔÐÐÐÐˆs�dÐÑÔÐÕÔÑÔÐÐÕÔˆsÑÔÐÕÔˆsÑÔÐÐÕÔ�dÑÔÐÐÑÐÐÐÐÐÑÐÕÕÔÐÑÔÑÔÐÐÐÐÐð ×+Ò+¨GÑ4Ô4ˆØÐˆu˜Š{ÐÐÐÕÔÐÐÐÐˆu˜ÐÑÔÐÕÔÑÔÐÐÕÔˆuÑÔÐÕÔˆuÑÔÐÐÕÔ˜ÑÔÐÐÑÐÐÐÐÐÑÐÕÕÔÐÑÔÑÔÐÐÐÐÐð ×'Ò'¨°Ñ3Ô3ˆØÐˆt�tˆ|ÐÐÐÕÔÐÐÐÐˆt�tÐÑÔÐÕÔÑÔÐÐÕÔˆtÑÔÐÕÔˆtÑÔÐÐÕÔ�tÑÔÐÐÑÐÐÐÐÐÑÐÕÕÔÐÑÔÑÔÐÐÐÐÐð ×+Ò+¨GÑ4Ô4ˆØÐˆu˜Š{ÐÐÐÕÔÐÐÐÐˆu˜ÐÑÔÐÕÔÑÔÐÐÕÔˆuÑÔÐÕÔˆuÑÔÐÐÕÔ˜ÑÔÐÐÑÐÐÐÐÐÑÐÕÕÔÐÑÔÑÔÐÐÐÐÐÐÐr   c           
     óB  — |                      ¦   «         }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  }dd|iz  }t          t          j	        |¦  «        ¦  «        ‚d	x}x}}d
„ |D ¦   «         }d}d}	t          ||	¦  «        }
t          |
¦  «        }||k    }|�s5t          j        d|fd||f¦  «        t          j        |¦  «        dt	          j        ¦   «         v st          j        t          ¦  «        rt          j        t          ¦  «        nddt	          j        ¦   «         v st          j        t          ¦  «        rt          j        t          ¦  «        ndt          j        |¦  «        t          j        |	¦  «        t          j        |
¦  «        t          j        |¦  «        dœz  }dd|iz  }t          t          j	        |¦  «        ¦  «        ‚d	x}x}x}x}	x}
}d	S )zLEnsure map_styles table remains exactly 30 records after injection attempts.r5   r=   rF   rG   ÚstylesrI   rN   rO   Nc                ó   — g | ]	}|j         ‘Œ
S r   )rX   )r„   r9   s     r   r‡   z_TestMapStyleSQLInjectionImmunity.test_database_integrity_after_sqli_barrage.<locals>.<listcomp>Â   s   € Ð-Ð-Ð- �”Ð-Ð-Ð-r   r6   rÜ   )z[%(py1)s == %(py12)s
{%(py12)s = %(py3)s(%(py10)s
{%(py10)s = %(py4)s(%(py6)s, %(py8)s)
})
}Úlistrœ   )rK   rL   r˜   rM   rO   rÃ   rÿ   úassert %(py14)srQ   )Úlist_stylesrG   rY   rZ   r[   r\   r]   r^   ra   rb   rœ   r  )rž   r   r  rt   ru   ri   rv   rw   rk   rÌ   r  Ú@py_assert11r  ry   s                 r   Ú*test_database_integrity_after_sqli_barragezKTestMapStyleSQLInjectionImmunity.test_database_integrity_after_sqli_barrage¾   s¸  € à×$Ò$Ñ&Ô&ˆÝ�6‰{Œ{Ð ˜bÐ ˆ{˜bÒ Ð Ð Ð Õ Ô Ð Ð Ð Ð ˆ{˜bÐ Ñ Ô Ð Õ Ô Ñ Ô Ð Ð Õ Ô �sÑ Ô Ð Õ Ô �sÑ Ô Ð Ð Ð Õ Ô Ñ Ô Ð Ð Õ Ô �6Ñ Ô Ð Õ Ô �6Ñ Ô Ð Ð Õ Ô ˆ{Ñ Ô Õ Ô ˜bÑ Ô Ð Ð Ñ Ð Ð Ð Ð Ð Ñ Ð Õ Õ Ô Ð Ñ Ô Ñ Ô Ð Ð Ð Ð Ð Ð Ð Ø-Ð- fÐ-Ñ-Ô-ÐC¸AÐC¸rÐCµe¸A¸r±l´lÐCµ°lÑ1CÔ1CÐCÐ-Ð1CÒCÐCÐCÑCÕCÔCÐCÐCÐCÐCÐ-Ð1CÐCÑCÔCÕCÔCÐ-ÑCÔCÐCÕCÔCÑCÔCÐCÐCÕCÔCµÑCÔCÐCÕCÔCµÑCÔCÐCÐCÐCÕCÔCÑCÔCÐCÐCÕCÔCµeÑCÔCÐCÕCÔCµeÑCÔCÐCÐCÕCÔC¸AÑCÔCÕCÔC¸rÑCÔCÕCÔC°lÑCÔCÕCÔCÐ1CÑCÔCÐCÐCÑCÐCÐCÐCÐCÐCÑCÐCÕCÕCÔCÐCÑCÔCÑCÔCÐCÐCÐCÐCÐCÐCÐCÐCÐCÐCÐCÐCÐCÐCÐCr   N)r   r	   r  r¡   r   r/   rÒ   )
rÓ   rÔ   rÕ   rÖ   ÚSQLI_PAYLOADSrÅ   r  r  r  r  r   r   r   r  r  ’   s­   € € € € € ØMÐMð 	Ø&Ø+Ø+Ø-Ø,ØØØØØØ'ØØØØ0ØØˆe‰Ø%ð'€Mð, „[×Ò˜Y¨Ñ6Ô6ðð ð ñ 7Ô6ðð$Dð Dð Dð Dð Dð Dr   r  c                  óÎ   — e Zd ZdZdd„Zdd„Zdd„Zdd„Zej	         
                    dd	d
g¦  «        dd„¦   «         Zej	         
                    dddg¦  «        dd„¦   «         ZdS )Ú&TestMapStyleRecoveryAndSchemaIntegrityzKTest auto-creation, recovery from partial/empty DBs, and CHECK constraints.r   r/   c           
     ó–
  — t          j        d¬¦  «        }	 t          j                             |ddd¦  «        }t          j        }|j        } ||¦  «        }| }|sæddt          j        ¦   «         v st          j	        t          ¦  «        rt          j
        t          ¦  «        ndt          j
        |¦  «        t          j
        |¦  «        dt          j        ¦   «         v st          j	        |¦  «        rt          j
        |¦  «        ndt          j
        |¦  «        d	œz  }t          t          j        |¦  «        ¦  «        ‚d
x}x}x}}t          |¬¦  «        }t          j        }|j        } ||¦  «        }|sæddt          j        ¦   «         v st          j	        t          ¦  «        rt          j
        t          ¦  «        ndt          j
        |¦  «        t          j
        |¦  «        dt          j        ¦   «         v st          j	        |¦  «        rt          j
        |¦  «        ndt          j
        |¦  «        d	œz  }	t          t          j        |	¦  «        ¦  «        ‚d
x}x}}|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        }
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
        |¦  «        t          j
        |¦  «        t          j
        |¦  «        t          j
        |¦  «        dœz  }dd|iz  }t          t          j        |¦  «        ¦  «        ‚d
x}
x}x}x}x}}t'          j        |d¬¦  «         d
S # t'          j        |d¬¦  «         w xY w)zTService automatically creates missing directory, database file, and seeds 30 styles.Úfe_recovery_r   ÚnestedÚdeepr   zfassert not %(py7)s
{%(py7)s = %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.path
}.exists
}(%(py5)s)
}r%   Ú
missing_db)rJ   r:   r˜   r;   r<   Nr   zbassert %(py7)s
{%(py7)s = %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.path
}.isfile
}(%(py5)s)
}r5   r=   ©zi%(py7)s
{%(py7)s = %(py0)s(%(py5)s
{%(py5)s = %(py3)s
{%(py3)s = %(py1)s.list_styles
}()
})
} == %(py10)srG   Úsvc©rJ   rK   rL   r;   r<   rÃ   rþ   rÿ   rì   rE   )zx%(py9)s
{%(py9)s = %(py0)s(%(py7)s
{%(py7)s = %(py3)s
{%(py3)s = %(py1)s.get_tiles_for_style
}(%(py5)s)
})
} == %(py12)s)rJ   rK   rL   r;   r<   r@   rÿ   r  rQ   Tr!   )r#   r$   r%   r&   r'   Úexistsr[   r\   rY   r]   r^   ra   rb   r	   Úisfiler  rG   rZ   rc   r(   r)   )rž   r*   r  rh   rj   rç   rË   rw   r  ro   rt   ri   r  rÐ   r  r  rl   ry   s                     r   Ú0test_missing_database_file_and_dir_auto_recoveryzWTestMapStyleRecoveryAndSchemaIntegrity.test_missing_database_file_and_dir_auto_recoveryÈ   sd  € åÔ!¨Ð8Ñ8Ô8ˆð		6ÝœŸš f¨h¸ÀÑPÔPˆJÝ”wÐ1�w”~Ð1�~�~ jÑ1Ô1Ð1Ð1Ð1Ð1Ð1Ð1Ð1Ð1Õ1Ô1Ñ1Ô1Ð1Ð1Õ1Ô1•rÑ1Ô1Ð1Õ1Ô1•rÑ1Ô1Ð1Ð1Õ1Ô1�wÑ1Ô1Õ1Ô1�~Ñ1Ô1Ð1Õ1Ô1Ñ1Ô1Ð1Ð1Õ1Ô1 jÑ1Ô1Ð1Õ1Ô1 jÑ1Ô1Ð1Ð1Õ1Ô1Ð1Ñ1Ô1Ð1Ð1Ñ1Ð1Õ1Õ1Ô1Ð1Ñ1Ô1Ñ1Ô1Ð1Ð1Ð1Ð1Ð1Ð1Ð1Ð1Ð1å!¨*Ð5Ñ5Ô5ˆCÝ”7Ð-�7”>Ð-�>�> *Ñ-Ô-Ð-Ð-Ð-Ð-Ð-Õ-Ô-Ñ-Ô-Ð-Ð-Õ-Ô-•2Ñ-Ô-Ð-Õ-Ô-•2Ñ-Ô-Ð-Ð-Õ-Ô-�7Ñ-Ô-Õ-Ô-�>Ñ-Ô-Ð-Õ-Ô-Ñ-Ô-Ð-Ð-Õ-Ô- *Ñ-Ô-Ð-Õ-Ô- *Ñ-Ô-Ð-Ð-Õ-Ô-Ð-Ñ-Ô-Ð-Ð-Ñ-Ð-Õ-Õ-Ô-Ð-Ñ-Ô-Ñ-Ô-Ð-Ð-Ð-Ð-Ð-Ð-Ð-Ø”Ð/��Ñ(Ô(Ð/•3Ð(Ñ)Ô)Ð/¨RÐ/Ð)¨RÒ/Ð/Ð/Ñ/Õ/Ô/Ð/Ð/Ð/Ð/Ð)¨RÐ/Ñ/Ô/Ð/Õ/Ô/Ñ/Ô/Ð/Ð/Õ/Ô/•3Ñ/Ô/Ð/Õ/Ô/•3Ñ/Ô/Ð/Ð/Ð/Õ/Ô/Ñ/Ô/Ð/Ð/Õ/Ô/�sÑ/Ô/Ð/Õ/Ô/�sÑ/Ô/Ð/Ð/Õ/Ô/�Ñ/Ô/Õ/Ô/Ð(Ñ/Ô/Õ/Ô/Ð)Ñ/Ô/Õ/Ô/¨RÑ/Ô/Ð/Ð/Ñ/Ð/Ð/Ð/Ð/Ð/Ñ/Ð/Õ/Õ/Ô/Ð/Ñ/Ô/Ñ/Ô/Ð/Ð/Ð/Ð/Ð/Ð/Ð/Ð/Ð/Ð/Ð/ØÔ.ÐPÐ/HÐPÐ.Ð.Ð/HÑIÔIÐP•3ÐIÑJÔJÐPÈbÐPÐJÈbÒPÐPÐPÑPÕPÔPÐPÐPÐPÐPÐJÈbÐPÑPÔPÐPÕPÔPÑPÔPÐPÐPÕPÔP•3ÑPÔPÐPÕPÔP•3ÑPÔPÐPÐPÐPÕPÔPÑPÔPÐPÐPÕPÔP�sÑPÔPÐPÕPÔP�sÑPÔPÐPÐPÕPÔPÐ.ÑPÔPÕPÔPÐ/HÑPÔPÕPÔPÐIÑPÔPÕPÔPÐJÑPÔPÕPÔPÈbÑPÔPÐPÐPÑPÐPÐPÐPÐPÐPÑPÐPÕPÕPÔPÐPÑPÔPÑPÔPÐPÐPÐPÐPÐPÐPÐPÐPÐPÐPÐPÐPÐPåŒM˜&°Ð5Ñ5Ô5Ð5Ð5Ð5ø�FŒM˜&°Ð5Ñ5Ô5Ð5Ð5øøøs   —TT0 Ô0Uc           	     ó	  — t          j        d¬¦  «        }	 t          j                             |d¦  «        }t          |d¦  «        5 }	 ddd¦  «         n# 1 swxY w Y   t          j        }|j        } ||¦  «        }d}||k    }|�st          j        d|fd||f¦  «        d	t          j
        ¦   «         v st          j        t          ¦  «        rt          j        t          ¦  «        nd	t          j        |¦  «        t          j        |¦  «        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}x}x}}t          |¬¦  «        }t          j        }|j        } ||¦  «        }d}||k    }|�st          j        d|fd||f¦  «        d	t          j
        ¦   «         v st          j        t          ¦  «        rt          j        t          ¦  «        nd	t          j        |¦  «        t          j        |¦  «        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}x}x}}|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}}t%          j        |d¬¦  «         dS # t%          j        |d¬¦  «         w xY w)zQService recovers from a pre-existing 0-byte file by initializing DDL and seeding.Ú	fe_empty_r   zempty.dbÚwbNr   r=   )zh%(py7)s
{%(py7)s = %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.path
}.getsize
}(%(py5)s)
} == %(py10)sr%   Úempty_db)rJ   r:   r˜   r;   r<   rÃ   rþ   rÿ   r   )ú>)zg%(py7)s
{%(py7)s = %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.path
}.getsize
}(%(py5)s)
} > %(py10)sr5   r  rG   r  r   Tr!   )r#   r$   r%   r&   r'   ÚopenÚgetsizerY   rZ   r[   r\   r]   r^   ra   rb   r	   r  rG   r(   r)   )rž   r*   r'  r�   rh   rj   rç   r  rË   rÐ   r  r  rt   ri   s                 r   Ú'test_zero_byte_empty_file_auto_recoveryzNTestMapStyleRecoveryAndSchemaIntegrity.test_zero_byte_empty_file_auto_recoveryÖ   sè  € åÔ!¨Ð5Ñ5Ô5ˆð
	6Ý”w—|’| F¨JÑ7Ô7ˆHÝ�h Ñ%Ô%ð ¨Øðð ð ñ ô ð ð ð ð ð ð øøøð ð ð ð å”7Ð1�7”?Ð1�?�? 8Ñ,Ô,Ð1°Ð1Ð,°Ò1Ð1Ð1Ñ1Õ1Ô1Ð1Ð1Ð1Ð1Ð,°Ð1Ñ1Ô1Ð1Õ1Ô1Ñ1Ô1Ð1Ð1Õ1Ô1•2Ñ1Ô1Ð1Õ1Ô1•2Ñ1Ô1Ð1Ð1Õ1Ô1�7Ñ1Ô1Õ1Ô1�?Ñ1Ô1Ð1Õ1Ô1Ñ1Ô1Ð1Ð1Õ1Ô1 8Ñ1Ô1Ð1Õ1Ô1 8Ñ1Ô1Ð1Ð1Õ1Ô1Ð,Ñ1Ô1Õ1Ô1°Ñ1Ô1Ð1Ð1Ñ1Ð1Ð1Ð1Ð1Ð1Ñ1Ð1Õ1Õ1Ô1Ð1Ñ1Ô1Ñ1Ô1Ð1Ð1Ð1Ð1Ð1Ð1Ð1Ð1Ð1Ð1Ð1å!¨(Ð3Ñ3Ô3ˆCÝ”7Ð0�7”?Ð0�?�? 8Ñ,Ô,Ð0¨qÐ0Ð,¨qÒ0Ð0Ð0Ñ0Õ0Ô0Ð0Ð0Ð0Ð0Ð,¨qÐ0Ñ0Ô0Ð0Õ0Ô0Ñ0Ô0Ð0Ð0Õ0Ô0•2Ñ0Ô0Ð0Õ0Ô0•2Ñ0Ô0Ð0Ð0Õ0Ô0�7Ñ0Ô0Õ0Ô0�?Ñ0Ô0Ð0Õ0Ô0Ñ0Ô0Ð0Ð0Õ0Ô0 8Ñ0Ô0Ð0Õ0Ô0 8Ñ0Ô0Ð0Ð0Õ0Ô0Ð,Ñ0Ô0Õ0Ô0¨qÑ0Ô0Ð0Ð0Ñ0Ð0Ð0Ð0Ð0Ð0Ñ0Ð0Õ0Õ0Ô0Ð0Ñ0Ô0Ñ0Ô0Ð0Ð0Ð0Ð0Ð0Ð0Ð0Ð0Ð0Ð0Ð0Ø”Ð/��Ñ(Ô(Ð/•3Ð(Ñ)Ô)Ð/¨RÐ/Ð)¨RÒ/Ð/Ð/Ñ/Õ/Ô/Ð/Ð/Ð/Ð/Ð)¨RÐ/Ñ/Ô/Ð/Õ/Ô/Ñ/Ô/Ð/Ð/Õ/Ô/•3Ñ/Ô/Ð/Õ/Ô/•3Ñ/Ô/Ð/Ð/Ð/Õ/Ô/Ñ/Ô/Ð/Ð/Õ/Ô/�sÑ/Ô/Ð/Õ/Ô/�sÑ/Ô/Ð/Ð/Õ/Ô/�Ñ/Ô/Õ/Ô/Ð(Ñ/Ô/Õ/Ô/Ð)Ñ/Ô/Õ/Ô/¨RÑ/Ô/Ð/Ð/Ñ/Ð/Ð/Ð/Ð/Ð/Ñ/Ð/Õ/Õ/Ô/Ð/Ñ/Ô/Ñ/Ô/Ð/Ð/Ð/Ð/Ð/Ð/Ð/Ð/Ð/Ð/Ð/åŒM˜&°Ð5Ñ5Ô5Ð5Ð5Ð5ø�FŒM˜&°Ð5Ñ5Ô5Ð5Ð5øøøs0   —0Q+ ÁAÁ	Q+ ÁAÁQ+ ÁAÁO6Q+ Ñ+Rc           	     ó.  — t          j        d¬¦  «        }	 t          j                             |d¦  «        }t          |¬¦  «        }|                     ¦   «         5 }|                     d¦  «         |                     ¦   «          ddd¦  «         n# 1 swxY w Y   |                     ¦   «         5 }| 	                    ¦   «         }|                     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¦  «         n# 1 swxY w Y   t          |¬¦  «        }|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}}t+          j        |d¬¦  «         dS # t+          j        |d¬¦  «         w xY w)zEIf database has fewer than 30 styles, MapStyleService re-seeds to 30.Úfe_partial_r   z
partial.dbr   z+DELETE FROM map_styles WHERE biome_code > 5NzSELECT count(*) FROM map_stylesr   é   r=   )z%(py1)s == %(py4)s)rK   r˜   zassert %(py6)srM   r5   r  rG   Úrecovered_svcr   rþ   rÿ   Tr!   )r#   r$   r%   r&   r'   r	   Ú_get_connectionÚexecuteÚcommitÚcursorÚfetchonerY   rZ   r^   ra   rb   r  rG   r[   r\   r]   r(   r)   )rž   r*   Ú
partial_dbr  ÚconnÚcurrk   rj   rt   rŸ   rv   r/  ri   rç   r  rË   rÐ   r  s                     r   Ú*test_partial_database_auto_reseed_recoveryzQTestMapStyleRecoveryAndSchemaIntegrity.test_partial_database_auto_reseed_recoveryå   s¤  € åÔ!¨Ð7Ñ7Ô7ˆð	6ÝœŸš f¨lÑ;Ô;ˆJÝ!¨*Ð5Ñ5Ô5ˆCà×$Ò$Ñ&Ô&ð ¨$Ø—’ÐJÑKÔKÐKØ—’‘”�ðð ð ñ ô ð ð ð ð ð ð øøøð ð ð ð ð
 ×$Ò$Ñ&Ô&ð .¨$Ø—k’k‘m”m�Ø—’Ð=Ñ>Ô>Ð>Ø—|’|‘~”~ aÔ(Ð-¨AÐ-Ð(¨AÒ-Ð-Ð-Ð-Õ-Ô-Ð-Ð-Ð-Ð-Ð(¨AÐ-Ñ-Ô-Õ-Ô-Ð(Ñ-Ô-Õ-Ô-¨AÑ-Ô-Ð-Ð-Ñ-Ð-Ð-Ð-Ð-Ð-Ñ-Ð-Õ-Õ-Ô-Ð-Ñ-Ô-Ñ-Ô-Ð-Ð-Ð-Ð-Ð-Ð-Ð-ð.ð .ð .ñ .ô .ð .ð .ð .ð .ð .ð .øøøð .ð .ð .ð .õ ,°JÐ?Ñ?Ô?ˆMØ$Ô0Ð9Ð0Ð0Ñ2Ô2Ð9•3Ð2Ñ3Ô3Ð9°rÐ9Ð3°rÒ9Ð9Ð9Ñ9Õ9Ô9Ð9Ð9Ð9Ð9Ð3°rÐ9Ñ9Ô9Ð9Õ9Ô9Ñ9Ô9Ð9Ð9Õ9Ô9•3Ñ9Ô9Ð9Õ9Ô9•3Ñ9Ô9Ð9Ð9Ð9Õ9Ô9Ñ9Ô9Ð9Ð9Õ9Ô9�}Ñ9Ô9Ð9Õ9Ô9�}Ñ9Ô9Ð9Ð9Õ9Ô9Ð0Ñ9Ô9Õ9Ô9Ð2Ñ9Ô9Õ9Ô9Ð3Ñ9Ô9Õ9Ô9°rÑ9Ô9Ð9Ð9Ñ9Ð9Ð9Ð9Ð9Ð9Ñ9Ð9Õ9Õ9Ô9Ð9Ñ9Ô9Ñ9Ô9Ð9Ð9Ð9Ð9Ð9Ð9Ð9Ð9Ð9Ð9Ð9åŒM˜&°Ð5Ñ5Ô5Ð5Ð5Ð5ø�FŒM˜&°Ð5Ñ5Ô5Ð5Ð5øøøsV   —AK< Á*BÂK< ÂBÂK< ÂBÂK< Â0C E<Å0K< Å<F Æ K< ÆF ÆE K< Ë<Lc                óÚ  — t          j        d¬¦  «        }	 t          j                             |d¦  «        }t          |d¦  «        5 }|                     d¦  «         ddd¦  «         n# 1 swxY w Y   t          j        t          j
        ¦  «        5  t          |¬¦  «         ddd¦  «         n# 1 swxY w Y   t          j        |d¬	¦  «         dS # t          j        |d¬	¦  «         w xY w)
zBGarbage-filled database file cleanly raises sqlite3.DatabaseError.Úfe_corrupt_r   z
corrupt.dbr&  s-   CORRUPTED_NON_SQLITE_GARBAGE_BYTES_1234567890Nr   Tr!   )r#   r$   r%   r&   r'   r)  ÚwriterÅ   rÆ   rÇ   ÚDatabaseErrorr	   r(   r)   )rž   r*   Ú
corrupt_dbr�   s       r   Ú2test_corrupted_database_file_raises_database_errorzYTestMapStyleRecoveryAndSchemaIntegrity.test_corrupted_database_file_raises_database_errorü   sg  € åÔ!¨Ð7Ñ7Ô7ˆð	6ÝœŸš f¨lÑ;Ô;ˆJÝ�j $Ñ'Ô'ð J¨1Ø—’ÐHÑIÔIÐIðJð Jð Jñ Jô Jð Jð Jð Jð Jð Jð Jøøøð Jð Jð Jð Jõ ”�wÔ4Ñ5Ô5ð 4ð 4Ý¨
Ð3Ñ3Ô3Ð3ð4ð 4ð 4ñ 4ô 4ð 4ð 4ð 4ð 4ð 4ð 4øøøð 4ð 4ð 4ð 4õ ŒM˜&°Ð5Ñ5Ô5Ð5Ð5Ð5ø�FŒM˜&°Ð5Ñ5Ô5Ð5Ð5øøøsS   —0C ÁA)ÁC Á)A-Á-C Á0A-Á1!C ÂB/Â#C Â/B3Â3C Â6B3Â7C ÃC*Úinvalid_biome_coder   rà   r,   r¡   r2   c                ó  — t          |¦  «        }|                     ¦   «         }t          j        t          j        ¦  «        5  |                     dd|› �|f¦  «         ddd¦  «         n# 1 swxY w Y   |                     ¦   «          dS )z=CHECK (biome_code BETWEEN 1 AND 255) rejects invalid inserts.a½  
                INSERT INTO map_styles (
                    style_id, biome_code, name_vi, name_en, theme_category,
                    theme_category_name, description, floor_color_hex, wall_color_hex,
                    path_color_hex, liquid_color_hex, ambient_light_hex, asset_dir, monster_family
                ) VALUES (?, ?, 'Vi', 'En', 'HOANG_DA_DA_NGOAI', 'T', 'D', '#111', '#222', '#333', '#444', '#555', 'a', 'm')
                Ú	STY_TEST_N)r   r3  rÅ   rÆ   rÇ   ÚIntegrityErrorr1  rÊ   )rž   r,   r?  r6  r7  s        r   Ú-test_schema_check_constraint_biome_code_rangezTTestMapStyleRecoveryAndSchemaIntegrity.test_schema_check_constraint_biome_code_range	  sÉ   € õ Ð'Ñ(Ô(ˆØ�kŠk‰mŒmˆÝŒ]�7Ô1Ñ2Ô2ð 
	ð 
	Ø�KŠKðð 2Ð/Ð1Ð1Ð3EÐFñ	ô 	ð 	ð
	ð 
	ð 
	ñ 
	ô 
	ð 
	ð 
	ð 
	ð 
	ð 
	ð 
	øøøð 
	ð 
	ð 
	ð 
	ð 	�
Š
‰Œˆˆˆs   ÁA*Á*A.Á1A.Úinvalid_tile_type_idrÚ   rE   c                óB  — t          |¬¦  «        }|                     ¦   «         5 }|                     ¦   «         }t          j        t
          j        ¦  «        5  |                     d|f¦  «         ddd¦  «         n# 1 swxY w Y   ddd¦  «         dS # 1 swxY w Y   dS )z?CHECK (tile_type_id BETWEEN 0 AND 19) rejects invalid tile IDs.r   a:  
                    INSERT INTO map_style_tiles (
                        style_id, tile_type_id, tile_type_name, texture_filename,
                        normal_filename, base_color_fallback
                    ) VALUES ('STY_01_HOANG_MANG_CO_LO', ?, 'INVALID', 't.png', 'n.png', '#111111')
                    N)r	   r0  r3  rÅ   rÆ   rÇ   rB  r1  )rž   r,   rD  r  r6  r7  s         r   Ú/test_schema_check_constraint_tile_type_id_rangezVTestMapStyleRecoveryAndSchemaIntegrity.test_schema_check_constraint_tile_type_id_range  s   € õ Ð&6Ð7Ñ7Ô7ˆØ× Ò Ñ"Ô"ð 	 dØ—+’+‘-”-ˆCÝ”�wÔ5Ñ6Ô6ð 	ð 	Ø—’ðð *Ð+ñô ð ð	ð 	ð 	ñ 	ô 	ð 	ð 	ð 	ð 	ð 	ð 	øøøð 	ð 	ð 	ð 	ð	ð 	ð 	ñ 	ô 	ð 	ð 	ð 	ð 	ð 	ð 	ð 	øøøð 	ð 	ð 	ð 	ð 	ð 	s5   ¥3BÁA<Á0BÁ<B 	Â BÂB 	ÂBÂBÂBNrÄ   )r,   r¡   r?  r2   r   r/   )r,   r¡   rD  r2   r   r/   )rÓ   rÔ   rÕ   rÖ   r#  r+  r8  r>  rÅ   r  r  rC  rF  r   r   r   r  r  Å   sÚ   € € € € € ØUÐUð6ð 6ð 6ð 6ð6ð 6ð 6ð 6ð6ð 6ð 6ð 6ð.6ð 6ð 6ð 6ð „[×ÒÐ1°A°s°8Ñ<Ô<ðð ð ñ =Ô<ðð" „[×ÒÐ3°b¸"°XÑ>Ô>ðð ð ñ ?Ô>ðð ð r   r  )r   r   )r   r   r   r	   )r   r   )#rÖ   Ú
__future__r   Úbuiltinsr[   Ú_pytest.assertion.rewriteÚ	assertionÚrewriterY   Úconcurrent.futuresr™   r%   r(   rÇ   r#   Úpathlibr   Útypingr   r   rÅ   Úserver.world.map_style_schemar   Úserver.world.map_style_servicer	   Úserver.world.map_style_typesr
   Úfixturer   r   r,   r.   rØ   r  r  r   r   r   ú<module>rS     s$  ððð ð #Ð "Ð "Ð "Ð "Ð "Ø  € € € € € € € € € € € € Ð Ð Ð Ð Ø 	€	€	€	Ø €€€Ø €€€Ø €€€Ø Ð Ð Ð Ð Ð Ø "Ð "Ð "Ð "Ð "Ð "Ð "Ð "à €€€à 1Ð 1Ð 1Ð 1Ð 1Ð 1Ø :Ð :Ð :Ð :Ð :Ð :Ø ;Ð ;Ð ;Ð ;Ð ;Ð ;ð €„�hÐÑÔðTð Tð Tñ  ÔðTð
 €„�hÐÑÔð6ð 6ð 6ñ  Ôð6ð
 „ð.ð .ð .ñ „ð.ð@ð @ð @ð @ð @ñ @ô @ð @ðF?ð ?ð ?ð ?ð ?ñ ?ô ?ð ?ðD0Dð 0Dð 0Dð 0Dð 0Dñ 0Dô 0Dð 0Dðfeð eð eð eð eñ eô eð eð eð er   