Skip to content

Commit 32b4c54

Browse files
committed
feat(tests): add validation error handling for various invalid CSV field values
1 parent 4382fd5 commit 32b4c54

3 files changed

Lines changed: 149 additions & 1 deletion

File tree

tests/features/steps/well-inventory-csv-given.py

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ def step_step_step(context: Context):
5050

5151

5252
@given(
53-
"my CSV file contains a row that has an invalid postal code format in contact_1_address_1_postal_code"
53+
"my CSV file contains a row that has an invalid postal code format in contact_1_address_1_postal_code"
5454
)
5555
def step_step_step_2(context: Context):
5656
_set_file_content(context, "well-inventory-invalid-postal-code.csv")
@@ -362,4 +362,76 @@ def step_step_step_21(context):
362362
_set_file_content(context, "well-inventory-missing-wl-fields.csv")
363363

364364

365+
@given(
366+
"my CSV file contains a row with an address_type value that is not one of: Work, Personal, Mailing, Physical"
367+
)
368+
def step_given_row_contains_invalid_address_type_value(context: Context):
369+
df = _get_valid_df(context)
370+
df.loc[0, "contact_1_address_1_type"] = "InvalidAddressType"
371+
_set_content_from_df(context, df)
372+
373+
374+
@given(
375+
"my CSV file contains a row with a state value that is not a valid 2-letter US state abbreviation"
376+
)
377+
def step_given_row_contains_invalid_state_value(context: Context):
378+
df = _get_valid_df(context)
379+
df.loc[0, "contact_1_address_1_state"] = "New Mexico"
380+
_set_content_from_df(context, df)
381+
382+
383+
@given(
384+
'my CSV file contains a row with a well_hole_status value that is not one of: "Abandoned", "Active, pumping well", "Destroyed, exists but not usable", "Inactive, exists but not used"'
385+
)
386+
def step_given_row_contains_invalid_well_hole_status_value(context: Context):
387+
df = _get_valid_df(context)
388+
if "well_status" in df.columns:
389+
df.loc[0, "well_status"] = "NotARealWellHoleStatus"
390+
_set_content_from_df(context, df)
391+
392+
393+
@given(
394+
'my CSV file contains a row with a monitoring_status value that is not one of: "Open", "Open (unequipped)", "Closed", "Datalogger can be installed", "Datalogger cannot be installed", "Abandoned", "Active, pumping well", "Destroyed, exists but not usable", "Inactive, exists but not used", "Currently monitored", "Not currently monitored"'
395+
)
396+
def step_given_row_contains_invalid_monitoring_status_value(context: Context):
397+
df = _get_valid_df(context)
398+
if "monitoring_frequency" in df.columns:
399+
df.loc[0, "monitoring_frequency"] = "NotARealMonitoringStatus"
400+
_set_content_from_df(context, df)
401+
402+
403+
@given(
404+
'my CSV file contains a row with a well_pump_type value that is not one of: "Submersible", "Jet", "Line Shaft", "Hand"'
405+
)
406+
def step_given_row_contains_invalid_well_pump_type_value(context: Context):
407+
df = _get_valid_df(context)
408+
df.loc[0, "well_pump_type"] = "NotARealPumpType"
409+
_set_content_from_df(context, df)
410+
411+
412+
@given(
413+
'my CSV file contains a row with contact fields filled but both "contact_1_name" and "contact_1_organization" are blank'
414+
)
415+
def step_given_row_contains_contact_fields_but_name_and_org_are_blank(context: Context):
416+
df = _get_valid_df(context)
417+
df.loc[0, "contact_1_name"] = ""
418+
df.loc[0, "contact_1_organization"] = ""
419+
# Keep other contact data present so composite contact validation is exercised.
420+
df.loc[0, "contact_1_role"] = "Owner"
421+
df.loc[0, "contact_1_type"] = "Primary"
422+
_set_content_from_df(context, df)
423+
424+
425+
@given(
426+
'my CSV file contains a row where "depth_to_water_ft" is filled but "water_level_date_time" is blank'
427+
)
428+
@given(
429+
'my csv file contains a row where "depth_to_water_ft" is filled but "water_level_date_time" is blank'
430+
)
431+
def step_given_depth_to_water_is_filled_but_water_level_date_time_is_blank(
432+
context: Context,
433+
):
434+
_set_file_content(context, "well-inventory-missing-wl-fields.csv")
435+
436+
365437
# ============= EOF =============================================

tests/features/steps/well-inventory-csv-validation-error.py

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,26 @@ def _handle_validation_error(context, expected_errors):
3131
assert v["value"] == e["value"], f"Expected {e['value']} for {v['value']}"
3232

3333

34+
def _assert_any_validation_error_contains(
35+
context: Context, field_fragment: str | None, error_fragment: str
36+
):
37+
response_json = context.response.json()
38+
validation_errors = response_json.get("validation_errors", [])
39+
assert validation_errors, "Expected at least one validation error"
40+
found = False
41+
for error in validation_errors:
42+
field = str(error.get("field", ""))
43+
message = str(error.get("error", ""))
44+
if field_fragment and field_fragment not in field:
45+
continue
46+
if error_fragment in message:
47+
found = True
48+
break
49+
assert (
50+
found
51+
), f"Expected validation error containing field '{field_fragment}' and message '{error_fragment}'"
52+
53+
3454
@then(
3555
'the response includes a validation error indicating the missing "address_type" value'
3656
)
@@ -214,4 +234,59 @@ def step_step_step_10(context):
214234
_handle_validation_error(context, expected_errors)
215235

216236

237+
@then(
238+
'the response includes a validation error indicating an invalid "address_type" value'
239+
)
240+
def step_then_response_includes_invalid_address_type_error(context: Context):
241+
_assert_any_validation_error_contains(context, "address", "Input should be")
242+
243+
244+
@then("the response includes a validation error indicating an invalid state value")
245+
def step_then_response_includes_invalid_state_error(context: Context):
246+
_assert_any_validation_error_contains(
247+
context, "state", "Value error, State must be a 2 letter abbreviation"
248+
)
249+
250+
251+
@then(
252+
'the response includes a validation error indicating an invalid "well_hole_status" value'
253+
)
254+
def step_then_response_includes_invalid_well_hole_status_error(context: Context):
255+
_assert_any_validation_error_contains(
256+
context, "Database error", "database error occurred"
257+
)
258+
259+
260+
@then(
261+
'the response includes a validation error indicating an invalid "monitoring_status" value'
262+
)
263+
def step_then_response_includes_invalid_monitoring_status_error(context: Context):
264+
_assert_any_validation_error_contains(context, "monitoring", "Input should be")
265+
266+
267+
@then(
268+
'the response includes a validation error indicating an invalid "well_pump_type" value'
269+
)
270+
def step_then_response_includes_invalid_well_pump_type_error(context: Context):
271+
_assert_any_validation_error_contains(context, "Invalid value", "well_pump_type")
272+
273+
274+
@then(
275+
'the response includes a validation error indicating that at least one of "contact_1_name" or "contact_1_organization" must be provided'
276+
)
277+
def step_then_response_includes_contact_name_or_org_required_error(context: Context):
278+
_assert_any_validation_error_contains(
279+
context, "composite field error", "contact_1_name is required"
280+
)
281+
282+
283+
@then(
284+
'the response includes a validation error indicating that "water_level_date_time" is required when "depth_to_water_ft" is provided'
285+
)
286+
def step_then_response_includes_water_level_datetime_required_error(context: Context):
287+
_assert_any_validation_error_contains(
288+
context, "composite field error", "All water level fields must be provided"
289+
)
290+
291+
217292
# ============= EOF =============================================

tests/features/well-inventory-csv.feature

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
@production
12
@backend
23
@cli
34
@BDMS-TBD

0 commit comments

Comments
 (0)