backend.tests.unit.components.reports.test_report_service
1import pytest 2from datetime import datetime, timedelta 3from backend.database.models import Entry, Worker 4from backend.components.reports.reportService import log_worker_entry, get_report_data 5 6 7# -------------------------------------------------------------------------- 8# Testy funkcji log_worker_entry 9# -------------------------------------------------------------------------- 10 11def test_log_worker_entry_success_removes_image(db_session, created_worker): 12 """ 13 Checks whether, on successful entry (code=0), the image is deleted (set to None), 14 even if it was passed to the function. 15 """ 16 fake_image = b'some_image_bytes' 17 18 entry = log_worker_entry( 19 code=0, 20 message="Access Granted", 21 worker=created_worker, 22 image=fake_image 23 ) 24 25 # Sprawdzamy czy obiekt został zwrócony i ma ID (czyli jest w sesji/bazie) 26 assert entry.id is not None 27 assert entry.worker_id == created_worker.id 28 assert entry.code == 0 29 # Kluczowy test logiki biznesowej: code 0 -> image musi być None 30 assert entry.face_image is None 31 32 33def test_log_worker_entry_failure_keeps_image(db_session, created_worker): 34 """ 35 Checks whether the photo is saved in the database on an unsuccessful entry (code!=0). 36 """ 37 fake_image = b'evidence_image_bytes' 38 39 entry = log_worker_entry( 40 code=1, # Błąd/Odmowa 41 message="Face mismatch", 42 worker=created_worker, 43 image=fake_image 44 ) 45 46 assert entry.id is not None 47 assert entry.code == 1 48 # Przy błędzie zdjęcie powinno zostać zachowane 49 assert entry.face_image == fake_image 50 51 52def test_log_worker_entry_unknown_person(db_session): 53 """ 54 Checks login entry for an unrecognized person (worker=None). 55 """ 56 entry = log_worker_entry( 57 code=2, 58 message="Unknown person", 59 worker=None, 60 image=b'intruder_face' 61 ) 62 63 assert entry.id is not None 64 assert entry.worker_id is None 65 assert entry.message == "Unknown person" 66 67 68# -------------------------------------------------------------------------- 69# Testy funkcji get_report_data 70# -------------------------------------------------------------------------- 71 72@pytest.fixture 73def report_data_setup(db_session, created_worker): 74 """ 75 A support fixture that creates a test data set for reporting. 76 77 Creates 4 entries with different dates and statuses. 78 """ 79 base_time = datetime(2023, 1, 1, 12, 0, 0) 80 81 # Drugi pracownik do testów filtrowania 82 worker2 = Worker(name="Adam Nowak", face_embedding=b'123', expiration_date=datetime.now(), secret="sec") 83 db_session.session.add(worker2) 84 db_session.session.commit() 85 86 entries = [ 87 # 1. Wpis poprawny, Worker 1, Data: base_time (najstarszy) 88 Entry(worker_id=created_worker.id, code=0, message="OK", date=base_time), 89 90 # 2. Wpis błędny, Worker 1, Data: base_time + 1 dzień 91 Entry(worker_id=created_worker.id, code=1, message="Error", date=base_time + timedelta(days=1)), 92 93 # 3. Wpis poprawny, Worker 2, Data: base_time + 2 dni 94 Entry(worker_id=worker2.id, code=0, message="OK", date=base_time + timedelta(days=2)), 95 96 # 4. Wpis błędny, Brak Workera, Data: base_time + 3 dni (najnowszy) 97 Entry(worker_id=None, code=2, message="Unknown", date=base_time + timedelta(days=3)) 98 ] 99 100 db_session.session.add_all(entries) 101 db_session.session.commit() 102 103 return { 104 "base_time": base_time, 105 "worker1": created_worker, 106 "worker2": worker2 107 } 108 109 110def test_get_report_data_all(db_session, report_data_setup): 111 """Test downloading all data (no filters).""" 112 results = get_report_data() 113 114 assert len(results) == 4 115 # Sprawdzenie sortowania (domyślnie malejąco po dacie - najnowsze pierwsze) 116 assert results[0][0].message == "Unknown" # Najnowszy (+3 dni) 117 assert results[-1][0].message == "OK" # Najstarszy (+0 dni) 118 119 # Sprawdzenie czy zwraca krotki (Entry, Worker) 120 first_entry, first_worker = results[0] 121 assert isinstance(first_entry, Entry) 122 assert first_worker is None # Ten wpis nie miał workera 123 124 125def test_get_report_data_filter_by_worker(db_session, report_data_setup): 126 """Test filtering by employee ID.""" 127 worker1 = report_data_setup["worker1"] 128 129 results = get_report_data(worker_id=worker1.id) 130 131 # Worker 1 ma 2 wpisy 132 assert len(results) == 2 133 for entry, worker in results: 134 assert entry.worker_id == worker1.id 135 assert worker.id == worker1.id 136 137 138def test_get_report_data_filter_by_date(db_session, report_data_setup): 139 """Test filtering by date range.""" 140 base_time = report_data_setup["base_time"] 141 142 # Filtrujemy od dnia +1 do dnia +2 (powinny być 2 wpisy) 143 date_from = base_time + timedelta(days=1) 144 date_to = base_time + timedelta(days=2) 145 146 results = get_report_data(date_from=date_from, date_to=date_to) 147 148 assert len(results) == 2 149 messages = [r[0].message for r in results] 150 assert "Error" in messages # +1 dzień 151 assert "OK" in messages # +2 dni 152 153 154def test_get_report_data_filter_valid_invalid(db_session, report_data_setup): 155 """Test filtering by status (valid/invalid).""" 156 157 # 1. Tylko poprawne (code == 0) -> Powinny być 2 (jeden workera1, jeden workera2) 158 valid_results = get_report_data(show_valid=True, show_invalid=False) 159 assert len(valid_results) == 2 160 for r in valid_results: 161 assert r[0].code == 0 162 163 # 2. Tylko błędne (code != 0) -> Powinny być 2 164 invalid_results = get_report_data(show_valid=False, show_invalid=True) 165 assert len(invalid_results) == 2 166 for r in invalid_results: 167 assert r[0].code != 0 168 169 # 3. Oba zaznaczone -> Wszystkie 4 170 all_results = get_report_data(show_valid=True, show_invalid=True) 171 assert len(all_results) == 4 172 173 # 4. Żaden niezaznaczony -> Domyślnie wszystkie 4 (zgodnie z logiką funkcji) 174 none_results = get_report_data(show_valid=False, show_invalid=False) 175 assert len(none_results) == 4
def
test_log_worker_entry_success_removes_image(db_session, created_worker):
12def test_log_worker_entry_success_removes_image(db_session, created_worker): 13 """ 14 Checks whether, on successful entry (code=0), the image is deleted (set to None), 15 even if it was passed to the function. 16 """ 17 fake_image = b'some_image_bytes' 18 19 entry = log_worker_entry( 20 code=0, 21 message="Access Granted", 22 worker=created_worker, 23 image=fake_image 24 ) 25 26 # Sprawdzamy czy obiekt został zwrócony i ma ID (czyli jest w sesji/bazie) 27 assert entry.id is not None 28 assert entry.worker_id == created_worker.id 29 assert entry.code == 0 30 # Kluczowy test logiki biznesowej: code 0 -> image musi być None 31 assert entry.face_image is None
Checks whether, on successful entry (code=0), the image is deleted (set to None), even if it was passed to the function.
def
test_log_worker_entry_failure_keeps_image(db_session, created_worker):
34def test_log_worker_entry_failure_keeps_image(db_session, created_worker): 35 """ 36 Checks whether the photo is saved in the database on an unsuccessful entry (code!=0). 37 """ 38 fake_image = b'evidence_image_bytes' 39 40 entry = log_worker_entry( 41 code=1, # Błąd/Odmowa 42 message="Face mismatch", 43 worker=created_worker, 44 image=fake_image 45 ) 46 47 assert entry.id is not None 48 assert entry.code == 1 49 # Przy błędzie zdjęcie powinno zostać zachowane 50 assert entry.face_image == fake_image
Checks whether the photo is saved in the database on an unsuccessful entry (code!=0).
def
test_log_worker_entry_unknown_person(db_session):
53def test_log_worker_entry_unknown_person(db_session): 54 """ 55 Checks login entry for an unrecognized person (worker=None). 56 """ 57 entry = log_worker_entry( 58 code=2, 59 message="Unknown person", 60 worker=None, 61 image=b'intruder_face' 62 ) 63 64 assert entry.id is not None 65 assert entry.worker_id is None 66 assert entry.message == "Unknown person"
Checks login entry for an unrecognized person (worker=None).
@pytest.fixture
def
report_data_setup(db_session, created_worker):
73@pytest.fixture 74def report_data_setup(db_session, created_worker): 75 """ 76 A support fixture that creates a test data set for reporting. 77 78 Creates 4 entries with different dates and statuses. 79 """ 80 base_time = datetime(2023, 1, 1, 12, 0, 0) 81 82 # Drugi pracownik do testów filtrowania 83 worker2 = Worker(name="Adam Nowak", face_embedding=b'123', expiration_date=datetime.now(), secret="sec") 84 db_session.session.add(worker2) 85 db_session.session.commit() 86 87 entries = [ 88 # 1. Wpis poprawny, Worker 1, Data: base_time (najstarszy) 89 Entry(worker_id=created_worker.id, code=0, message="OK", date=base_time), 90 91 # 2. Wpis błędny, Worker 1, Data: base_time + 1 dzień 92 Entry(worker_id=created_worker.id, code=1, message="Error", date=base_time + timedelta(days=1)), 93 94 # 3. Wpis poprawny, Worker 2, Data: base_time + 2 dni 95 Entry(worker_id=worker2.id, code=0, message="OK", date=base_time + timedelta(days=2)), 96 97 # 4. Wpis błędny, Brak Workera, Data: base_time + 3 dni (najnowszy) 98 Entry(worker_id=None, code=2, message="Unknown", date=base_time + timedelta(days=3)) 99 ] 100 101 db_session.session.add_all(entries) 102 db_session.session.commit() 103 104 return { 105 "base_time": base_time, 106 "worker1": created_worker, 107 "worker2": worker2 108 }
A support fixture that creates a test data set for reporting.
Creates 4 entries with different dates and statuses.
def
test_get_report_data_all(db_session, report_data_setup):
111def test_get_report_data_all(db_session, report_data_setup): 112 """Test downloading all data (no filters).""" 113 results = get_report_data() 114 115 assert len(results) == 4 116 # Sprawdzenie sortowania (domyślnie malejąco po dacie - najnowsze pierwsze) 117 assert results[0][0].message == "Unknown" # Najnowszy (+3 dni) 118 assert results[-1][0].message == "OK" # Najstarszy (+0 dni) 119 120 # Sprawdzenie czy zwraca krotki (Entry, Worker) 121 first_entry, first_worker = results[0] 122 assert isinstance(first_entry, Entry) 123 assert first_worker is None # Ten wpis nie miał workera
Test downloading all data (no filters).
def
test_get_report_data_filter_by_worker(db_session, report_data_setup):
126def test_get_report_data_filter_by_worker(db_session, report_data_setup): 127 """Test filtering by employee ID.""" 128 worker1 = report_data_setup["worker1"] 129 130 results = get_report_data(worker_id=worker1.id) 131 132 # Worker 1 ma 2 wpisy 133 assert len(results) == 2 134 for entry, worker in results: 135 assert entry.worker_id == worker1.id 136 assert worker.id == worker1.id
Test filtering by employee ID.
def
test_get_report_data_filter_by_date(db_session, report_data_setup):
139def test_get_report_data_filter_by_date(db_session, report_data_setup): 140 """Test filtering by date range.""" 141 base_time = report_data_setup["base_time"] 142 143 # Filtrujemy od dnia +1 do dnia +2 (powinny być 2 wpisy) 144 date_from = base_time + timedelta(days=1) 145 date_to = base_time + timedelta(days=2) 146 147 results = get_report_data(date_from=date_from, date_to=date_to) 148 149 assert len(results) == 2 150 messages = [r[0].message for r in results] 151 assert "Error" in messages # +1 dzień 152 assert "OK" in messages # +2 dni
Test filtering by date range.
def
test_get_report_data_filter_valid_invalid(db_session, report_data_setup):
155def test_get_report_data_filter_valid_invalid(db_session, report_data_setup): 156 """Test filtering by status (valid/invalid).""" 157 158 # 1. Tylko poprawne (code == 0) -> Powinny być 2 (jeden workera1, jeden workera2) 159 valid_results = get_report_data(show_valid=True, show_invalid=False) 160 assert len(valid_results) == 2 161 for r in valid_results: 162 assert r[0].code == 0 163 164 # 2. Tylko błędne (code != 0) -> Powinny być 2 165 invalid_results = get_report_data(show_valid=False, show_invalid=True) 166 assert len(invalid_results) == 2 167 for r in invalid_results: 168 assert r[0].code != 0 169 170 # 3. Oba zaznaczone -> Wszystkie 4 171 all_results = get_report_data(show_valid=True, show_invalid=True) 172 assert len(all_results) == 4 173 174 # 4. Żaden niezaznaczony -> Domyślnie wszystkie 4 (zgodnie z logiką funkcji) 175 none_results = get_report_data(show_valid=False, show_invalid=False) 176 assert len(none_results) == 4
Test filtering by status (valid/invalid).