@@ -482,7 +482,7 @@ def test_well_inventory_db_contents_with_waterlevels(tmp_path):
482482 "sample_method" : "Steel-tape measurement" ,
483483 "data_quality" : "Water level accurate to within two hundreths of a foot" ,
484484 "water_level_notes" : "Attempted measurement" ,
485- "mp_height_ft" : 2 .5 ,
485+ "mp_height_ft" : 3 .5 ,
486486 "level_status" : "Water level not affected" ,
487487 }
488488 )
@@ -530,6 +530,136 @@ def test_well_inventory_db_contents_with_waterlevels(tmp_path):
530530 assert observation .sample == sample
531531
532532
533+ def test_measuring_point_height_ft_used_for_thing_and_observation (tmp_path ):
534+ """When measuring_point_height_ft is provided it is used for the thing's (MeasuringPointHistory) and observation's measuring_point_height values."""
535+ row = _minimal_valid_well_inventory_row ()
536+ row .update (
537+ {
538+ "measuring_point_height_ft" : 3.5 ,
539+ "water_level_date_time" : "2025-02-15T10:30:00" ,
540+ "depth_to_water_ft" : "8" ,
541+ "sample_method" : "Steel-tape measurement" ,
542+ "data_quality" : "Water level accurate to within two hundreths of a foot" ,
543+ "water_level_notes" : "Attempted measurement" ,
544+ }
545+ )
546+
547+ file_path = tmp_path / "well-inventory-blank-depth.csv"
548+ with file_path .open ("w" , encoding = "utf-8" , newline = "" ) as f :
549+ writer = csv .DictWriter (f , fieldnames = list (row .keys ()))
550+ writer .writeheader ()
551+ writer .writerow (row )
552+
553+ result = well_inventory_csv (file_path )
554+ assert result .exit_code == 0 , result .stderr
555+
556+ with session_ctx () as session :
557+ things = session .query (Thing ).all ()
558+ observations = session .query (Observation ).all ()
559+
560+ assert len (things ) == 1
561+ assert things [0 ].measuring_point_height == 3.5
562+ assert len (observations ) == 1
563+ assert observations [0 ].measuring_point_height == 3.5
564+
565+
566+ def test_mp_height_used_for_thing_and_observation_when_measuring_point_height_ft_blank (
567+ tmp_path ,
568+ ):
569+ """When depth to water is provided and measuring_point_height_ft is blank the mp_height value should be used for the thing's (MeasuringPointHistory) and observation's measuring_point_height."""
570+ row = _minimal_valid_well_inventory_row ()
571+ row .update (
572+ {
573+ "measuring_point_height_ft" : "" ,
574+ "water_level_date_time" : "2025-02-15T10:30:00" ,
575+ "depth_to_water_ft" : "8" ,
576+ "sample_method" : "Steel-tape measurement" ,
577+ "data_quality" : "Water level accurate to within two hundreths of a foot" ,
578+ "water_level_notes" : "Attempted measurement" ,
579+ "mp_height" : 4.0 ,
580+ }
581+ )
582+
583+ file_path = tmp_path / "well-inventory-blank-depth.csv"
584+ with file_path .open ("w" , encoding = "utf-8" , newline = "" ) as f :
585+ writer = csv .DictWriter (f , fieldnames = list (row .keys ()))
586+ writer .writeheader ()
587+ writer .writerow (row )
588+
589+ result = well_inventory_csv (file_path )
590+ assert result .exit_code == 0 , result .stderr
591+
592+ with session_ctx () as session :
593+ things = session .query (Thing ).all ()
594+ observations = session .query (Observation ).all ()
595+
596+ assert len (things ) == 1
597+ assert things [0 ].measuring_point_height == 4.0
598+ assert len (observations ) == 1
599+ assert observations [0 ].measuring_point_height == 4.0
600+
601+
602+ def test_null_mp_height_allowed (tmp_path ):
603+ """A null measuring_point_height_ft and mp_height are allowed when depth to water is provided, and results in null measuring_point_height for the thing and observation."""
604+ row = _minimal_valid_well_inventory_row ()
605+ row .update (
606+ {
607+ "measuring_point_height_ft" : "" ,
608+ "water_level_date_time" : "2025-02-15T10:30:00" ,
609+ "depth_to_water_ft" : 8 ,
610+ "sample_method" : "Steel-tape measurement" ,
611+ "data_quality" : "Water level accurate to within two hundreths of a foot" ,
612+ "water_level_notes" : "Attempted measurement" ,
613+ }
614+ )
615+
616+ file_path = tmp_path / "well-inventory-blank-depth.csv"
617+ with file_path .open ("w" , encoding = "utf-8" , newline = "" ) as f :
618+ writer = csv .DictWriter (f , fieldnames = list (row .keys ()))
619+ writer .writeheader ()
620+ writer .writerow (row )
621+
622+ result = well_inventory_csv (file_path )
623+ assert result .exit_code == 0 , result .stderr
624+
625+ with session_ctx () as session :
626+ things = session .query (Thing ).all ()
627+ observations = session .query (Observation ).all ()
628+
629+ assert len (things ) == 1
630+ assert things [0 ].measuring_point_height is None
631+ assert len (observations ) == 1
632+ assert observations [0 ].value == 8
633+ assert observations [0 ].measuring_point_height is None
634+
635+
636+ def test_conflicting_mp_heights_raises_error (tmp_path ):
637+ """
638+ When both measuring_point_height_ft and mp_height are provided, an inequality (conflict) should raise an error.
639+ """
640+ row = _minimal_valid_well_inventory_row ()
641+
642+ row .update (
643+ {
644+ "measuring_point_height_ft" : 3.5 ,
645+ "mp_height" : 4.0 ,
646+ }
647+ )
648+
649+ file_path = tmp_path / "well-inventory-blank-depth.csv"
650+ with file_path .open ("w" , encoding = "utf-8" , newline = "" ) as f :
651+ writer = csv .DictWriter (f , fieldnames = list (row .keys ()))
652+ writer .writeheader ()
653+ writer .writerow (row )
654+
655+ result = well_inventory_csv (file_path )
656+ assert result .exit_code == 1 , result .stderr
657+ assert (
658+ result .payload ["validation_errors" ][0 ]["error" ]
659+ == "Conflicting values for measuring point height: mp_height and measuring_point_height_ft"
660+ )
661+
662+
533663def test_blank_depth_to_water_still_creates_water_level_records (tmp_path ):
534664 """Blank depth-to-water is treated as missing while preserving the attempted measurement."""
535665 row = _minimal_valid_well_inventory_row ()
@@ -540,7 +670,7 @@ def test_blank_depth_to_water_still_creates_water_level_records(tmp_path):
540670 "sample_method" : "Steel-tape measurement" ,
541671 "data_quality" : "Water level accurate to within two hundreths of a foot" ,
542672 "water_level_notes" : "Attempted measurement" ,
543- "mp_height_ft" : 2 .5 ,
673+ "mp_height_ft" : 3 .5 ,
544674 }
545675 )
546676
@@ -564,7 +694,7 @@ def test_blank_depth_to_water_still_creates_water_level_records(tmp_path):
564694 "2025-02-15T10:30:00Z"
565695 )
566696 assert observations [0 ].value is None
567- assert observations [0 ].measuring_point_height == 2 .5
697+ assert observations [0 ].measuring_point_height == 3 .5
568698
569699
570700def test_rerunning_same_well_inventory_csv_is_idempotent ():
0 commit comments