187 lines
7.6 KiBLFS
Python
187 lines
7.6 KiBLFS
Python
"""
|
|
Tests for pdf-excel-diff task.
|
|
|
|
Verifies that the agent correctly identifies:
|
|
1. Deleted employees (present in PDF but not in current Excel)
|
|
2. Modified employee records (different values between PDF and Excel)
|
|
"""
|
|
|
|
import json
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
OUTPUT_FILE = Path("/root/diff_report.json")
|
|
EXPECTED_FILE = Path("/verifier/expected_output.json")
|
|
|
|
|
|
class TestFileExists:
|
|
"""Test that the output file exists and is valid JSON."""
|
|
|
|
def test_output_file_exists(self):
|
|
"""Verify the output file was created."""
|
|
assert OUTPUT_FILE.exists(), f"Output file not found at {OUTPUT_FILE}"
|
|
|
|
def test_output_file_valid_json(self):
|
|
"""Verify the output file contains valid JSON."""
|
|
assert OUTPUT_FILE.exists(), "Output file does not exist"
|
|
with open(OUTPUT_FILE) as f:
|
|
try:
|
|
json.load(f)
|
|
except json.JSONDecodeError as e:
|
|
pytest.fail(f"Output file is not valid JSON: {e}")
|
|
|
|
def test_output_has_required_keys(self):
|
|
"""Verify the output has the required structure."""
|
|
assert OUTPUT_FILE.exists(), "Output file does not exist"
|
|
with open(OUTPUT_FILE) as f:
|
|
data = json.load(f)
|
|
|
|
assert "deleted_employees" in data, "Missing 'deleted_employees' key"
|
|
assert "modified_employees" in data, "Missing 'modified_employees' key"
|
|
assert isinstance(data["deleted_employees"], list), "'deleted_employees' should be a list"
|
|
assert isinstance(data["modified_employees"], list), "'modified_employees' should be a list"
|
|
|
|
|
|
class TestDeletedEmployees:
|
|
"""Test detection of deleted employees."""
|
|
|
|
def test_correct_deleted_count(self):
|
|
"""Verify the correct number of deleted employees was found."""
|
|
with open(OUTPUT_FILE) as f:
|
|
output = json.load(f)
|
|
with open(EXPECTED_FILE) as f:
|
|
expected = json.load(f)
|
|
|
|
assert len(output["deleted_employees"]) == len(
|
|
expected["deleted_employees"]
|
|
), f"Expected {len(expected['deleted_employees'])} deleted employees, found {len(output['deleted_employees'])}"
|
|
|
|
def test_correct_deleted_ids(self):
|
|
"""Verify the correct employee IDs were identified as deleted."""
|
|
with open(OUTPUT_FILE) as f:
|
|
output = json.load(f)
|
|
with open(EXPECTED_FILE) as f:
|
|
expected = json.load(f)
|
|
|
|
output_ids = set(output["deleted_employees"])
|
|
expected_ids = set(expected["deleted_employees"])
|
|
|
|
missing = expected_ids - output_ids
|
|
extra = output_ids - expected_ids
|
|
|
|
assert missing == set(), f"Failed to detect deleted employees: {missing}"
|
|
assert extra == set(), f"Incorrectly marked as deleted: {extra}"
|
|
|
|
|
|
class TestModifiedEmployees:
|
|
"""Test detection of modified employee records."""
|
|
|
|
def test_correct_modified_count(self):
|
|
"""Verify the correct number of modifications was found."""
|
|
with open(OUTPUT_FILE) as f:
|
|
output = json.load(f)
|
|
with open(EXPECTED_FILE) as f:
|
|
expected = json.load(f)
|
|
|
|
assert len(output["modified_employees"]) == len(
|
|
expected["modified_employees"]
|
|
), f"Expected {len(expected['modified_employees'])} modifications, found {len(output['modified_employees'])}"
|
|
|
|
def test_modified_employee_structure(self):
|
|
"""Verify each modification entry has required fields."""
|
|
with open(OUTPUT_FILE) as f:
|
|
output = json.load(f)
|
|
|
|
for mod in output["modified_employees"]:
|
|
assert "id" in mod, "Modification entry missing 'id' field"
|
|
assert "field" in mod, "Modification entry missing 'field' field"
|
|
assert "old_value" in mod, "Modification entry missing 'old_value' field"
|
|
assert "new_value" in mod, "Modification entry missing 'new_value' field"
|
|
|
|
def test_correct_modified_ids(self):
|
|
"""Verify the correct employee IDs were identified as modified."""
|
|
with open(OUTPUT_FILE) as f:
|
|
output = json.load(f)
|
|
with open(EXPECTED_FILE) as f:
|
|
expected = json.load(f)
|
|
|
|
output_ids = {m["id"] for m in output["modified_employees"]}
|
|
expected_ids = {m["id"] for m in expected["modified_employees"]}
|
|
|
|
missing = expected_ids - output_ids
|
|
extra = output_ids - expected_ids
|
|
|
|
assert missing == set(), f"Failed to detect modifications for: {missing}"
|
|
assert extra == set(), f"Incorrectly detected modifications for: {extra}"
|
|
|
|
def test_correct_modified_fields(self):
|
|
"""Verify the correct fields were identified as modified."""
|
|
with open(OUTPUT_FILE) as f:
|
|
output = json.load(f)
|
|
with open(EXPECTED_FILE) as f:
|
|
expected = json.load(f)
|
|
|
|
# Create lookup by ID
|
|
expected_by_id = {m["id"]: m for m in expected["modified_employees"]}
|
|
output_by_id = {m["id"]: m for m in output["modified_employees"]}
|
|
|
|
for emp_id, exp_mod in expected_by_id.items():
|
|
if emp_id in output_by_id:
|
|
out_mod = output_by_id[emp_id]
|
|
assert out_mod["field"] == exp_mod["field"], f"For {emp_id}: expected field '{exp_mod['field']}', got '{out_mod['field']}'"
|
|
|
|
def test_correct_modified_values(self):
|
|
"""Verify the old and new values are correct."""
|
|
with open(OUTPUT_FILE) as f:
|
|
output = json.load(f)
|
|
with open(EXPECTED_FILE) as f:
|
|
expected = json.load(f)
|
|
|
|
# Create lookup by ID
|
|
expected_by_id = {m["id"]: m for m in expected["modified_employees"]}
|
|
output_by_id = {m["id"]: m for m in output["modified_employees"]}
|
|
|
|
for emp_id, exp_mod in expected_by_id.items():
|
|
if emp_id in output_by_id:
|
|
out_mod = output_by_id[emp_id]
|
|
|
|
# Compare old values (handle type differences)
|
|
exp_old = exp_mod["old_value"]
|
|
out_old = out_mod["old_value"]
|
|
if isinstance(exp_old, (int, float)) and isinstance(out_old, (int, float)):
|
|
assert abs(exp_old - out_old) < 0.01, f"For {emp_id}: expected old_value {exp_old}, got {out_old}"
|
|
else:
|
|
assert str(exp_old) == str(out_old), f"For {emp_id}: expected old_value '{exp_old}', got '{out_old}'"
|
|
|
|
# Compare new values
|
|
exp_new = exp_mod["new_value"]
|
|
out_new = out_mod["new_value"]
|
|
if isinstance(exp_new, (int, float)) and isinstance(out_new, (int, float)):
|
|
assert abs(exp_new - out_new) < 0.01, f"For {emp_id}: expected new_value {exp_new}, got {out_new}"
|
|
else:
|
|
assert str(exp_new) == str(out_new), f"For {emp_id}: expected new_value '{exp_new}', got '{out_new}'"
|
|
|
|
|
|
class TestIntegration:
|
|
"""Integration tests verifying overall correctness."""
|
|
|
|
def test_full_comparison(self):
|
|
"""Full comparison of output vs expected."""
|
|
with open(OUTPUT_FILE) as f:
|
|
output = json.load(f)
|
|
with open(EXPECTED_FILE) as f:
|
|
expected = json.load(f)
|
|
|
|
# Check deleted employees
|
|
assert set(output["deleted_employees"]) == set(expected["deleted_employees"]), "Deleted employees do not match"
|
|
|
|
# Check modified employees count
|
|
assert len(output["modified_employees"]) == len(expected["modified_employees"]), "Modified employees count does not match"
|
|
|
|
# Check each modification
|
|
expected_mods = {(m["id"], m["field"]): m for m in expected["modified_employees"]}
|
|
output_mods = {(m["id"], m["field"]): m for m in output["modified_employees"]}
|
|
|
|
assert set(expected_mods.keys()) == set(output_mods.keys()), "Modified employee/field combinations do not match"
|