
    ɣh~0                        d Z ddlZddlmc mZ ddlZddlZddl	Z	ddl
Z
ddlZddlmZ ddlmZ ddlmZ  e
j$                  d      d        Z e
j$                  d      d	        Z e
j$                  d      d
        Z e
j$                  d      d        Zd Z e
j$                  d      d        Z e
j$                  d      d        Z e
j$                  d      d        Z e
j$                  d      d        Z e
j$                  d      d        Z e
j$                  d      d        Z e
j$                  d      d        Zd Z e
j$                  d      d        Z y)aH  
conftest.py

Purpose:
  Pytest configuration and fixtures for the automated testing system.
  Provides isolated test environments with in-memory databases, temporary
  directories, and pre-configured test users and clients.

Fixtures:
  - app: Flask application instance configured for testing
  - client: Flask test client for HTTP requests
  - db: In-memory SQLite database with test schema
  - temp_static: Temporary directory for image file testing
  - test_users: Pre-created test users with different permission levels
  - authenticated_clients: Pre-authenticated test clients
    N)Flask)
create_app)get_dbfunction)scopec               #     K   i } g d}|D ]$  }t         j                  j                  |      | |<   & t        j                         \  }}t        j
                         }t         j                  j                  |d      }t        j                  |d       |t         j                  d<   |t         j                  d<   dt         j                  d<   d	t         j                  d
<   dt         j                  d<   dt         j                  d<   dt         j                  d<   t               }d|j                  d<   d|j                  d<   |j                         5  t                ddd       | |j                         5  ddlm} t        |d      r&|j                   j#                          t%        |d       ddd       t        j"                  |       t        j&                  |       ddl}	|	j+                  |d       |D ]>  }| |   | |   t         j                  |<   t         j                  j-                  |d       @ y# 1 sw Y   xY w# 1 sw Y   xY ww)z6Create and configure a Flask app instance for testing.)DATABASE_PATHUSER_PHOTOS_DIR_REAL
SECRET_KEYENABLE_HSTSzUser-photosT)exist_okr	   r
   z test-secret-key-for-testing-onlyr   0r   10000LOGIN_MAX_FAILS1LOGIN_WINDOW_SECONDSLOGIN_LOCK_SECONDSTESTINGFWTF_CSRF_ENABLEDNr   )g	_database)ignore_errors)osenvirongettempfilemkstempmkdtemppathjoinmakedirsr   configapp_contextinit_test_databaseflaskr   hasattrr   closedelattrunlinkshutilrmtreepop)
original_envenv_keyskeydb_fddb_pathtemp_statictemp_user_photosappr   r*   s
             AC:\Users\algun\Documents\ceba web\Ceba - Github\tests\conftest.pyr4   r4      s     LUHJJNN3/S  %%'NE7 ""$Kww||K?KK 40 #*BJJ)9BJJ%&ABJJ| #BJJ} %,BJJ !),BJJ%&'*BJJ#$ ,C CJJy%*CJJ!" 
	 
 I 
	1k"KKA{#	 
 HHUOIIg
MM+TM2 (*3/BJJsOJJNN3%	 ' 
	 
	s7   EIH>I89I
1BI>II
IIc                 "    | j                         S )zCreate a Flask test client.)test_clientr4   s    r5   clientr9   X   s     ??    c              #   n   K   | j                         5  t                ddd       y# 1 sw Y   yxY ww)z)Get database connection for the test app.N)r#   r   r8   s    r5   dbr<   ^   s$      
	h 
		s   5)	525c                 @    t         j                  j                  d      S )z$Get temporary static directory path.r
   )r   r   r   r8   s    r5   r2   r2   e   s     ::>>011r:   c                     t         j                  j                  d      } t        j                  |       }t        j
                  |_        |j                  d       |j                  d       |j                  d       |j                  d       |j                  d       |j                  d       |j                  d       |j                          |j                          y	)
z6Initialize the test database with the required schema.r	   z
        CREATE TABLE IF NOT EXISTS users (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            username TEXT UNIQUE NOT NULL,
            password_hash TEXT NOT NULL,
            is_admin BOOLEAN NOT NULL DEFAULT 0
        )
    a  
        CREATE TABLE IF NOT EXISTS cameras (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            user_id INTEGER NOT NULL,
            camera_id INTEGER NOT NULL,
            camera_name TEXT NOT NULL,
            file_paths TEXT,
            added_to_map INTEGER DEFAULT 0,
            location TEXT,
            FOREIGN KEY (user_id) REFERENCES users (id)
        )
    a  
        CREATE TABLE IF NOT EXISTS markers (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            user_id INTEGER NOT NULL,
            type TEXT NOT NULL,
            camera_id TEXT,
            latitude REAL NOT NULL,
            longitude REAL NOT NULL,
            added_to_map INTEGER DEFAULT 0,
            name TEXT,
            FOREIGN KEY (user_id) REFERENCES users (id)
        )
    a&  
        CREATE TABLE IF NOT EXISTS login_attempts (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            username TEXT NOT NULL,
            ip TEXT NOT NULL,
            fail_count INTEGER DEFAULT 0,
            last_failed_at INTEGER,
            locked_until INTEGER
        )
    z
        CREATE TABLE IF NOT EXISTS login_ip_attempts (
            ip TEXT PRIMARY KEY,
            fail_count INTEGER DEFAULT 0,
            last_failed_at INTEGER,
            locked_until INTEGER
        )
    aX  
        CREATE TABLE IF NOT EXISTS auth_log (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            ts INTEGER NOT NULL,
            ip TEXT NOT NULL,
            user_id INTEGER,
            username TEXT,
            event TEXT NOT NULL,
            detail TEXT,
            FOREIGN KEY (user_id) REFERENCES users (id)
        )
    a  
        CREATE TABLE IF NOT EXISTS admin_audit (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            ts INTEGER NOT NULL,
            ip TEXT NOT NULL,
            admin_user_id INTEGER NOT NULL,
            target_user_id INTEGER,
            action TEXT NOT NULL,
            detail TEXT,
            FOREIGN KEY (admin_user_id) REFERENCES users (id),
            FOREIGN KEY (target_user_id) REFERENCES users (id)
        )
    N)
r   r   r   sqlite3connectRowrow_factoryexecutecommitr'   )r1   r<   s     r5   r$   r$   k   s     jjnn_-G		!B[[BN JJ  	 JJ  	 JJ  	 JJ 	 		 JJ  	 JJ  	 JJ  	 IIKHHJr:   c                    | j                         5  t        j                  j                  d      }t	        j
                  |      }t        j                  |_        i }t        j                  dj                  d      t        j                               j                  d      }|j                  dd|df      }|j                  dddd|d<   t        j                  d	j                  d      t        j                               j                  d      }|j                  dd
|df      }|j                  d
d	dd|d<   t        j                  dj                  d      t        j                               j                  d      }|j                  dd|df      }|j                  dddd|d<   |j                          |j!                          |cddd       S # 1 sw Y   yxY w)z3Create test users with different permission levels.r	   testpass123zutf-8zFINSERT INTO users (username, password_hash, is_admin) VALUES (?, ?, ?)testuserF)idusernamepasswordis_adminregularadminpass123	testadminTadminlimitedpass123limiteduserlimitedN)r#   r   r   r   r?   r@   rA   rB   bcrypthashpwencodegensaltdecoderC   	lastrowidrD   r'   )r4   r1   r<   usersregular_password_hashcursoradmin_password_hashlimited_password_hashs           r5   
test_usersr^      s    
	**..1__W%  !'m.B.B7.KV^^M] ^ e efm nT.6

 """%	
i %mmN,A,A',JFNNL\]ddelmT-t4

 ""#&	
g !'.>.E.Eg.NPVP^P^P` a h hip qT159

 ""%(	
i 			

a 
		s   F:GGc                 H    |d   }| j                  d|d   |d   d       | S )z5Create an authenticated test client for regular user.rL   /loginrI   rJ   rI   rJ   datapostr9   r^   users      r5   authenticated_client_regularrh     :     i D
KK$$ K  Mr:   c                 H    |d   }| j                  d|d   |d   d       | S )z3Create an authenticated test client for admin user.rO   r`   rI   rJ   ra   rb   rd   rf   s      r5   authenticated_client_adminrk     s:     gD
KK$$ K  Mr:   c                 H    |d   }| j                  d|d   |d   d       | S )z5Create an authenticated test client for limited user.rR   r`   rI   rJ   ra   rb   rd   rf   s      r5   authenticated_client_limitedrm     ri   r:   c                  0    dddddddddddddd	dd
S )z'Provide sample camera data for testing.123456789012zTest Camera 1)	camera_idcamera_name987654321098zTest Camera 212345zInvalid Camera12345678901a )validvalid_2invalid_short_idinvalid_non_numericinvalid_empty_name r{   r:   r5   sample_camera_datar|   '  sM    
 (*

 (*

 !+

 (+ 

 (
# r:   c                      dddddddddS )	z&Provide sample image data for testing.z%PICT_20240101_120000_123456789012.jpgz
image/jpegs    JFIF  H H  )filenamecontent_typerc   z$IMG_20240101_130000_123456789012.pngz	image/pngs   PNG

   IHDR      )jpgpngr{   r{   r:   r5   sample_image_datar   B  s-    
 @(]
 ?'Z
 r:   c                  .    ddddddddd	d
dddddddS )z'Provide sample marker data for testing.cameraro   g[?g͏F@g3@zTest Camera Marker)typerp   latitude	longitudenamefaunagDܜJF@gOY3@zWild Boar Sighting)r   r   r   r   	structureg-y<-?F@g>e3@zFeeding Station)camera_markerfauna_markerstructure_markerr{   r{   r:   r5   sample_marker_datar   S  sH    
 '!"(
 !"(	
  !"%	
 r:   c                 d   | j                         5  t        j                  j                  d      }t	        j
                  |      }t        j                  |_        |j                  d       |j                  d       |j                          |j                          ddd       y# 1 sw Y   yxY w)z,Helper function to clear rate limiting data.r	   zDELETE FROM login_attemptszDELETE FROM login_ip_attemptsN)r#   r   r   r   r?   r@   rA   rB   rC   rD   r'   )r4   r1   r<   s      r5   clear_rate_limit_datar   m  sq    		**..1__W%  	

/0


23
		

 
		s   BB&&B/c              #   L    K   t                 fd}| t                yw)z4Clear rate limiting data before and after each test.c                      t                y )Nr   r8   s   r5   	clear_nowz$clear_rate_limits.<locals>.clear_now  s    c"r:   Nr   )r4   r   s   ` r5   clear_rate_limitsr   {  s'      ## O #s   !$)!__doc__builtins@py_builtins_pytest.assertion.rewrite	assertionrewrite
@pytest_arr   r   r?   pytestrS   r%   r   app_modules.initializerr   app_modules.dbr   fixturer4   r9   r<   r2   r$   r^   rh   rk   rm   r|   r   r   r   r   r{   r:   r5   <module>r      s  "  	      . ! j!8& "8&v j! "
 j! " j!2 "2
bJ j!2 "2j j! " j! " j! " j! "4 j! "  j! "2 j! "r:   