From b3b351605c9462e90ae3c0450a8f3121f8be50e6 Mon Sep 17 00:00:00 2001 From: Oscar Madera <80536682+oscarbol09@users.noreply.github.com> Date: Mon, 20 Jul 2026 13:20:53 -0500 Subject: [PATCH] fix(salary): detect city column from header token, not exact match (#201) convert_salary_excel.py detected the city column via exact membership (h_lower in CITY_PATTERNS), so real headers like "City Name", "City/Kommune", or "Kommune " never matched and every company was written with an empty city field. Switches to header_matches(h, CITY_PATTERNS) - the same whole-token matcher already used for the company, count, index, and ID columns. Same bug class as #151 (company column); bare "City"/"Kommune" inputs are unaffected. Regression test covers bare and suffixed headers. By @oscarbol09. --- tests/test_convert_salary_excel.py | 16 ++++++++++++++++ tools/convert_salary_excel.py | 3 +-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/tests/test_convert_salary_excel.py b/tests/test_convert_salary_excel.py index 7a2394f..2ce1ca2 100644 --- a/tests/test_convert_salary_excel.py +++ b/tests/test_convert_salary_excel.py @@ -104,6 +104,22 @@ class DetectColumnTypeTests(unittest.TestCase): companies[0]["categories"]["salary"], {"index": 105.5} ) + def test_parse_sheet_detects_city_column_with_token_header(self): + # City headers are matched with the same token-based header_matches() + # used for the company column, not exact string equality. Real-world + # sheets rarely use the bare token "City" or "Kommune" alone; headers + # like "City Name" / "City/Kommune" must still be detected as the city + # column (previously silently left as city_col=None -> empty city). + for header in ("City", "City Name", "Kommune", "City/Kommune"): + with self.subTest(header=header): + ws = FakeWorksheet([ + ("Company", header, "Salary"), + ("Example Corp", "Aarhus", 105.5), + ]) + companies = parse_sheet(ws) + self.assertEqual(len(companies), 1) + self.assertEqual(companies[0]["city"], "Aarhus") + def test_skips_free_text_column(self): # A free-text "Notes" column must not become a bogus salary category. ws = FakeWorksheet([ diff --git a/tools/convert_salary_excel.py b/tools/convert_salary_excel.py index 88e8fbf..30e28ab 100644 --- a/tools/convert_salary_excel.py +++ b/tools/convert_salary_excel.py @@ -114,10 +114,9 @@ def parse_sheet(ws, sheet_label=None): company_col = None city_col = None for i, h in enumerate(headers): - h_lower = h.lower() if header_matches(h, COMPANY_PATTERNS): company_col = i - elif h_lower in CITY_PATTERNS: + elif header_matches(h, CITY_PATTERNS): city_col = i if company_col is None: